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

Collapse All | Expand All

(-)model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java (+2 lines)
Lines 62-67 Link Here
62
	intArrayStack = new int[30][];
62
	intArrayStack = new int[30][];
63
	this.options = options;
63
	this.options = options;
64
	this.javadocParser.checkDocComment = false;
64
	this.javadocParser.checkDocComment = false;
65
	
66
	this.setStatementsRecovery(false);
65
}
67
}
66
/*
68
/*
67
 * Will clear the comment stack when looking
69
 * Will clear the comment stack when looking
(-)dom/org/eclipse/jdt/core/dom/ASTParser.java (-1 / +14 lines)
Lines 26-31 Link Here
26
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
26
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
27
import org.eclipse.jdt.internal.compiler.ast.Statement;
27
import org.eclipse.jdt.internal.compiler.ast.Statement;
28
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
28
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
29
import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
30
import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
31
import org.eclipse.jdt.internal.compiler.parser.Scanner;
29
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
32
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
30
import org.eclipse.jdt.internal.core.*;
33
import org.eclipse.jdt.internal.core.*;
31
import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
34
import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
Lines 914-920 Link Here
914
		}
917
		}
915
		switch(this.astKind) {
918
		switch(this.astKind) {
916
			case K_STATEMENTS :
919
			case K_STATEMENTS :
917
				ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true);
920
				ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true, true);
921
				RecoveryScannerData data = constructorDeclaration.compilationResult.recoveryScannerData;
922
				if(data != null) {
923
					Scanner scanner = converter.scanner;
924
					converter.scanner = new RecoveryScanner(scanner, data.removeUnused());
925
					converter.docParser.scanner = converter.scanner;
926
					converter.scanner.setSource(scanner.source);
927
					
928
				}
918
				RecordedParsingInformation recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
929
				RecordedParsingInformation recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
919
				int[][] comments = recordedParsingInformation.commentPositions;
930
				int[][] comments = recordedParsingInformation.commentPositions;
920
				if (comments != null) {
931
				if (comments != null) {
Lines 1000-1005 Link Here
1000
	private void propagateErrors(ASTNode astNode, IProblem[] problems) {
1011
	private void propagateErrors(ASTNode astNode, IProblem[] problems) {
1001
		ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(problems);
1012
		ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(problems);
1002
		astNode.accept(syntaxErrorPropagator);
1013
		astNode.accept(syntaxErrorPropagator);
1014
		ASTRecoveryPropagator recoveryPropagator = new ASTRecoveryPropagator(problems);
1015
		astNode.accept(recoveryPropagator);
1003
	}
1016
	}
1004
	
1017
	
1005
	private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, ASTNode node, RecordedParsingInformation recordedParsingInformation) {
1018
	private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, ASTNode node, RecordedParsingInformation recordedParsingInformation) {
(-)dom/org/eclipse/jdt/core/dom/ASTNode.java (+11 lines)
Lines 1034-1039 Link Here
1034
	public static final int PROTECT = 4;
1034
	public static final int PROTECT = 4;
1035
1035
1036
	/**
1036
	/**
1037
	 * Flag constant (bit mask, value 8) indicating that this node
1038
	 * or a part of this node is recovered from source that contains
1039
	 * a syntax error detected in the vicinity.
1040
	 * <p>
1041
	 * The standard parser (<code>ASTParser</code>) sets this
1042
	 * flag on a node to indicate a recovered node.
1043
	 * </p>
1044
	 */
1045
	public static final int RECOVERED = 8;
1046
	
1047
	/**
1037
	 * int containing the node type in the top 16 bits and
1048
	 * int containing the node type in the top 16 bits and
1038
	 * flags in the bottom 16 bits; none set by default.
1049
	 * flags in the bottom 16 bits; none set by default.
1039
     * <p>
1050
     * <p>
(-)dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java (+8 lines)
Lines 18-23 Link Here
18
	public DefaultASTVisitor() {
18
	public DefaultASTVisitor() {
19
		super();
19
		super();
20
	}
20
	}
21
	
22
	/**
23
	 * 
24
	 */
25
	public DefaultASTVisitor(boolean visitDocTags) {
26
		super(visitDocTags);
27
	}
28
	
21
	protected boolean visitNode(ASTNode node) {
29
	protected boolean visitNode(ASTNode node) {
22
		return true;
30
		return true;
23
	}
31
	}
(-)dom/org/eclipse/jdt/core/dom/ASTConverter.java (-17 / +7 lines)
Lines 46-51 Link Here
46
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
46
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
47
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
47
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
48
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
48
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
49
import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
49
import org.eclipse.jdt.internal.compiler.parser.Scanner;
50
import org.eclipse.jdt.internal.compiler.parser.Scanner;
50
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
51
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
51
52
Lines 1190-1195 Link Here
1190
	}
1191
	}
1191
	
1192
	
1192
	public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
1193
	public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
1194
		if(unit.compilationResult.recoveryScannerData != null) {
1195
			this.scanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused());
1196
			this.docParser.scanner = this.scanner;
1197
		}
1193
		this.compilationUnitSource = source;
1198
		this.compilationUnitSource = source;
1194
		this.compilationUnitSourceLength = source.length;
1199
		this.compilationUnitSourceLength = source.length;
1195
		this.scanner.setSource(source, unit.compilationResult);
1200
		this.scanner.setSource(source, unit.compilationResult);
Lines 1248-1253 Link Here
1248
			}
1253
			}
1249
			ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
1254
			ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
1250
			compilationUnit.accept(syntaxErrorPropagator);
1255
			compilationUnit.accept(syntaxErrorPropagator);
1256
			ASTRecoveryPropagator recoveryPropagator = new ASTRecoveryPropagator(resizedProblems);
1257
			compilationUnit.accept(recoveryPropagator);
1251
			compilationUnit.setProblems(resizedProblems);
1258
			compilationUnit.setProblems(resizedProblems);
1252
		}
1259
		}
1253
		if (this.resolveBindings) {
1260
		if (this.resolveBindings) {
Lines 4237-4259 Link Here
4237
							return;
4244
							return;
4238
						}
4245
						}
4239
						break;
4246
						break;
4240
					case TerminalTokens.TokenNameLBRACE :
4241
						count++;
4242
						break;
4243
					case TerminalTokens.TokenNameRBRACE :
4244
						count--;
4245
						break;
4246
					case TerminalTokens.TokenNameLPAREN :
4247
						count++;
4248
						break;
4249
					case TerminalTokens.TokenNameRPAREN :
4250
						count--;
4251
						break;
4252
					case TerminalTokens.TokenNameLBRACKET :
4253
						count++;
4254
						break;
4255
					case TerminalTokens.TokenNameRBRACKET :
4256
						count--;
4257
				}
4247
				}
4258
			}
4248
			}
4259
		} catch(InvalidInputException e) {
4249
		} catch(InvalidInputException e) {
(-)compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java (-56 / +600 lines)
Lines 22-35 Link Here
22
22
23
import org.eclipse.jdt.core.compiler.CharOperation;
23
import org.eclipse.jdt.core.compiler.CharOperation;
24
import org.eclipse.jdt.core.compiler.InvalidInputException;
24
import org.eclipse.jdt.core.compiler.InvalidInputException;
25
import org.eclipse.jdt.internal.compiler.ASTVisitor;
25
import org.eclipse.jdt.internal.compiler.CompilationResult;
26
import org.eclipse.jdt.internal.compiler.CompilationResult;
26
import org.eclipse.jdt.internal.compiler.ast.*;
27
import org.eclipse.jdt.internal.compiler.ast.*;
27
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
28
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
28
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
29
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
29
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
30
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
30
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
31
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
32
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
33
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
31
import org.eclipse.jdt.internal.compiler.lookup.Binding;
34
import org.eclipse.jdt.internal.compiler.lookup.Binding;
32
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
35
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
36
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
33
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
37
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
34
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
38
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
35
import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
39
import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
Lines 76-81 Link Here
76
	
80
	
77
	public static byte rhs[] = null;
81
	public static byte rhs[] = null;
78
	
82
	
83
	public static int[] reverse_index = null;
84
	public static char[] recovery_templates_index = null;
85
	public static char[] recovery_templates = null;
86
	public static char[] statements_recovery_filter = null;
87
	
79
	public static long rules_compliance[] =  null;
88
	public static long rules_compliance[] =  null;
80
	
89
	
81
	public static final int RoundBracket = 0;
90
	public static final int RoundBracket = 0;
Lines 171-176 Link Here
171
	public boolean reportOnlyOneSyntaxError = false;
180
	public boolean reportOnlyOneSyntaxError = false;
172
	public boolean reportSyntaxErrorIsRequired = true;
181
	public boolean reportSyntaxErrorIsRequired = true;
173
	protected boolean restartRecovery;
182
	protected boolean restartRecovery;
183
	
184
	// statement recovery
185
//	public boolean statementRecoveryEnabled = true;
186
	protected boolean methodRecoveryActivated = false;
187
	protected boolean statementRecoveryActivated = false;
188
	protected TypeDeclaration[] recoveredTypes;
189
	protected int recoveredTypePtr;
190
	protected int nextTypeStart;
191
	
192
	public RecoveryScanner recoveryScanner;
193
	
174
	//scanner token 
194
	//scanner token 
175
	public Scanner scanner;
195
	public Scanner scanner;
176
	protected int[] stack = new int[StackIncrement];
196
	protected int[] stack = new int[StackIncrement];
Lines 298-303 Link Here
298
	Collections.sort(entries);
318
	Collections.sort(entries);
299
	buildFile(file, entries);
319
	buildFile(file, entries);
300
}
320
}
321
private static void buildFilesForRecoveryTemplates(
322
	String indexFilename,
323
	String templatesFilename,
324
	char[] newTerminalIndex,
325
	char[] newNonTerminalIndex,
326
	String[] newName,
327
	char[] newLhs,
328
	String[] tokens) throws IOException {
329
	
330
	int[] newReverse = computeReverseTable(newTerminalIndex, newNonTerminalIndex, newName);
331
	
332
	char[] newRecoveyTemplatesIndex = new char[newNonTerminalIndex.length];
333
	char[] newRecoveyTemplates = new char[newNonTerminalIndex.length];
334
	int newRecoveyTemplatesPtr = 0;
335
	
336
	for (int i = 0; i < tokens.length; i = i + 3) {
337
		if("3".equals(tokens[i])) { //$NON-NLS-1$
338
			int length = newRecoveyTemplates.length;
339
			if(length == newRecoveyTemplatesPtr + 1) {
340
				System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
341
			}
342
			newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
343
			
344
			int index = newLhs[Integer.parseInt(tokens[i + 1])];
345
			
346
			newRecoveyTemplatesIndex[index] = (char)newRecoveyTemplatesPtr;
347
			
348
			String token = tokens[i + 2].trim();
349
			java.util.StringTokenizer st = new java.util.StringTokenizer(new String(token), " ");  //$NON-NLS-1$
350
			String[] terminalNames = new String[st.countTokens()];
351
			int t = 0;
352
			while (st.hasMoreTokens()) {
353
				terminalNames[t++] = st.nextToken();
354
			}
355
			
356
			for (int j = 0; j < terminalNames.length; j++) {
357
				int symbol = getSymbol(terminalNames[j], newName, newReverse);
358
				if(symbol > -1) {
359
					length = newRecoveyTemplates.length;
360
					if(length == newRecoveyTemplatesPtr + 1) {
361
						System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
362
					}
363
					newRecoveyTemplates[newRecoveyTemplatesPtr++] = (char)symbol;
364
				}
365
			}
366
		}
367
	}
368
	newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
369
	System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[newRecoveyTemplatesPtr], 0, newRecoveyTemplatesPtr);
370
	
371
	buildFileForTable(indexFilename, newRecoveyTemplatesIndex);
372
	buildFileForTable(templatesFilename, newRecoveyTemplates);
373
}
374
private static void buildFilesForStatementsRecoveryFilter(
375
		String filename,
376
		char[] newNonTerminalIndex,
377
		char[] newLhs,
378
		String[] tokens) throws IOException {
379
		
380
		char[] newStatementsRecoveryFilter = new char[newNonTerminalIndex.length];
381
		
382
		for (int i = 0; i < tokens.length; i = i + 3) {
383
			if("4".equals(tokens[i])) { //$NON-NLS-1$
384
				int index = newLhs[Integer.parseInt(tokens[i + 1])];
385
				
386
				newStatementsRecoveryFilter[index] = 1;
387
			}
388
		}
389
		buildFileForTable(filename, newStatementsRecoveryFilter);
390
	}
301
private static void buildFileForCompliance(
391
private static void buildFileForCompliance(
302
		String file,
392
		String file,
303
		int length,
393
		int length,
Lines 450-456 Link Here
450
	buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
540
	buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
451
	buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
541
	buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
452
	buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
542
	buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
453
	buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
543
	char[] newTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
454
	char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
544
	char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
455
	buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
545
	buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
456
	
546
	
Lines 475-481 Link Here
475
		System.out.println(Messages.parser_incorrectPath); 
565
		System.out.println(Messages.parser_incorrectPath); 
476
		return;
566
		return;
477
	}
567
	}
478
	st = new java.util.StringTokenizer(new String(contents), "\t\n\r=#");  //$NON-NLS-1$
568
	st = new java.util.StringTokenizer(new String(contents), "\t\n\r#");  //$NON-NLS-1$
479
	tokens = new String[st.countTokens()];
569
	tokens = new String[st.countTokens()];
480
	j = 0;
570
	j = 0;
481
	while (st.hasMoreTokens()) {
571
	while (st.hasMoreTokens()) {
Lines 485-490 Link Here
485
	buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
575
	buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
486
	buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
576
	buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
487
	
577
	
578
	buildFilesForRecoveryTemplates(
579
			prefix + (++i) + ".rsc", //$NON-NLS-1$
580
			prefix + (++i) + ".rsc", //$NON-NLS-1$
581
			newTerminalIndex,
582
			newNonTerminalIndex,
583
			newName,
584
			newLhs,
585
			tokens);
586
	
587
	buildFilesForStatementsRecoveryFilter(
588
			prefix + (++i) + ".rsc", //$NON-NLS-1$
589
			newNonTerminalIndex,
590
			newLhs,
591
			tokens);
592
593
	
488
	System.out.println(Messages.parser_moveFiles); 
594
	System.out.println(Messages.parser_moveFiles); 
489
}
595
}
490
public static int in_symbol(int state) {
596
public static int in_symbol(int state) {
Lines 526-531 Link Here
526
	
632
	
527
	readableName = readReadableNameTable(READABLE_NAMES_FILE_NAME);
633
	readableName = readReadableNameTable(READABLE_NAMES_FILE_NAME);
528
	
634
	
635
	reverse_index = computeReverseTable(terminal_index, non_terminal_index, name);
636
	
637
	recovery_templates_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
638
	recovery_templates = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
639
	
640
	statements_recovery_filter = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
641
	
529
	base_action = lhs;
642
	base_action = lhs;
530
}
643
}
531
public static int nasi(int state) {
644
public static int nasi(int state) {
Lines 537-542 Link Here
537
protected static int original_state(int state) {
650
protected static int original_state(int state) {
538
	return -base_check(state);
651
	return -base_check(state);
539
}
652
}
653
protected static int[] computeReverseTable(char[] newTerminalIndex, char[] newNonTerminalIndex, String[] newName) {
654
	int[] newReverseTable = new int[newName.length];
655
	for (int j = 0; j < newName.length; j++) {
656
		found : {
657
			for (int k = 0; k < newTerminalIndex.length; k++) {
658
				if(newTerminalIndex[k] == j) {
659
					newReverseTable[j] = k;
660
					break found;
661
				}
662
			}
663
			for (int k = 0; k < newNonTerminalIndex.length; k++) {
664
				if(newNonTerminalIndex[k] == j) {
665
					newReverseTable[j] = -k;
666
					break found;
667
				}
668
			}
669
		}
670
	}
671
	return newReverseTable;
672
}
673
674
private static int getSymbol(String terminalName, String[] newName, int[] newReverse) {
675
	for (int j = 0; j < newName.length; j++) {
676
		if(terminalName.equals(newName[j])) {
677
			return newReverse[j];
678
		}
679
	}
680
	return -1;
681
}
682
540
protected static byte[] readByteTable(String filename) throws java.io.IOException {
683
protected static byte[] readByteTable(String filename) throws java.io.IOException {
541
684
542
	//files are located at Parser.class directory
685
	//files are located at Parser.class directory
Lines 703-708 Link Here
703
	
846
	
704
	// javadoc support
847
	// javadoc support
705
	this.javadocParser = new JavadocParser(this);	
848
	this.javadocParser = new JavadocParser(this);	
849
	
850
//	this.statementRecoveryEnabled = this.options.performStatementsRecovery;
706
}
851
}
707
protected void annotationRecoveryCheckPoint(int start, int end) {
852
protected void annotationRecoveryCheckPoint(int start, int end) {
708
	if(this.lastCheckPoint > start && this.lastCheckPoint < end) {
853
	if(this.lastCheckPoint > start && this.lastCheckPoint < end) {
Lines 768-773 Link Here
768
		if (this.referenceContext instanceof AbstractMethodDeclaration){
913
		if (this.referenceContext instanceof AbstractMethodDeclaration){
769
			element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
914
			element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
770
			this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
915
			this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
916
			if(this.statementRecoveryActivated) {
917
				element = element.add(new Block(0), 0);
918
			}
771
		} else {
919
		} else {
772
			/* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
920
			/* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
773
			if (this.referenceContext instanceof TypeDeclaration){
921
			if (this.referenceContext instanceof TypeDeclaration){
Lines 845-850 Link Here
845
			element = element.add(importRef, 0);
993
			element = element.add(importRef, 0);
846
			this.lastCheckPoint = importRef.declarationSourceEnd + 1;
994
			this.lastCheckPoint = importRef.declarationSourceEnd + 1;
847
		}
995
		}
996
		if(this.statementRecoveryActivated) {
997
			if(node instanceof Block) {
998
				Block block = (Block) node;
999
				element = element.add(block, 0);
1000
				this.lastCheckPoint = block.sourceEnd + 1;
1001
			} else if(node instanceof LocalDeclaration) {
1002
				LocalDeclaration statement = (LocalDeclaration) node;
1003
				element = element.add(statement, 0);
1004
				this.lastCheckPoint = statement.sourceEnd + 1;
1005
			} else if(node instanceof Expression) {
1006
				Expression statement = (Expression) node;
1007
				element = element.add(statement, 0);
1008
				if(statement.statementEnd != -1) {
1009
					this.lastCheckPoint = statement.statementEnd + 1;
1010
				} else {
1011
					this.lastCheckPoint = statement.sourceEnd + 1;
1012
				}
1013
			} else if(node instanceof Statement) {
1014
				Statement statement = (Statement) node;
1015
				element = element.add(statement, 0);
1016
				this.lastCheckPoint = statement.sourceEnd + 1;
1017
			}
1018
		}
848
	}
1019
	}
849
	return element;
1020
	return element;
850
}
1021
}
Lines 1133-1139 Link Here
1133
	annotationTypeDeclaration.javadoc = this.javadoc;
1304
	annotationTypeDeclaration.javadoc = this.javadoc;
1134
	this.javadoc = null;	
1305
	this.javadoc = null;	
1135
	pushOnAstStack(annotationTypeDeclaration);
1306
	pushOnAstStack(annotationTypeDeclaration);
1136
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
1307
	if(!this.statementRecoveryActivated &&
1308
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
1137
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
1309
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
1138
		this.problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration);
1310
		this.problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration);
1139
	}	
1311
	}	
Lines 2421-2427 Link Here
2421
protected void consumeEmptyClassMemberDeclaration() {
2593
protected void consumeEmptyClassMemberDeclaration() {
2422
	// ClassMemberDeclaration ::= ';'
2594
	// ClassMemberDeclaration ::= ';'
2423
	pushOnAstLengthStack(0);
2595
	pushOnAstLengthStack(0);
2424
	problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2596
	if(!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2425
	flushCommentsDefinedPriorTo(this.endStatementPosition);
2597
	flushCommentsDefinedPriorTo(this.endStatementPosition);
2426
}
2598
}
2427
protected void consumeEmptyMethodHeaderDefaultValue() {
2599
protected void consumeEmptyMethodHeaderDefaultValue() {
Lines 2489-2495 Link Here
2489
protected void consumeEmptyTypeDeclaration() {
2661
protected void consumeEmptyTypeDeclaration() {
2490
	// TypeDeclaration ::= ';' 
2662
	// TypeDeclaration ::= ';' 
2491
	pushOnAstLengthStack(0);
2663
	pushOnAstLengthStack(0);
2492
	problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2664
	if(!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2493
	flushCommentsDefinedPriorTo(this.endStatementPosition);
2665
	flushCommentsDefinedPriorTo(this.endStatementPosition);
2494
}
2666
}
2495
protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
2667
protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
Lines 2539-2544 Link Here
2539
			localDeclaration,
2711
			localDeclaration,
2540
			this.intStack[this.intPtr--]); 
2712
			this.intStack[this.intPtr--]); 
2541
	pushOnAstStack(iteratorForStatement);
2713
	pushOnAstStack(iteratorForStatement);
2714
	
2715
	iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
2542
}
2716
}
2543
protected void consumeEnhancedForStatementHeader(){
2717
protected void consumeEnhancedForStatementHeader(){
2544
	// EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
2718
	// EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
Lines 2547-2553 Link Here
2547
	this.expressionLengthPtr--;
2721
	this.expressionLengthPtr--;
2548
	final Expression collection = this.expressionStack[this.expressionPtr--];
2722
	final Expression collection = this.expressionStack[this.expressionPtr--];
2549
	statement.collection = collection;
2723
	statement.collection = collection;
2550
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
2724
	statement.sourceEnd = this.rParenPos;
2725
	
2726
	if(!this.statementRecoveryActivated &&
2727
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
2551
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
2728
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
2552
		this.problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection);
2729
		this.problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection);
2553
	}	
2730
	}	
Lines 2986-2992 Link Here
2986
3163
2987
	this.listLength = 0; // will be updated when reading super-interfaces
3164
	this.listLength = 0; // will be updated when reading super-interfaces
2988
	
3165
	
2989
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
3166
	if(!this.statementRecoveryActivated &&
3167
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
2990
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
3168
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
2991
		//TODO this code will be never run while 'enum' is an identifier in 1.3 scanner 
3169
		//TODO this code will be never run while 'enum' is an identifier in 1.3 scanner 
2992
		this.problemReporter().invalidUsageOfEnumDeclarations(enumDeclaration);
3170
		this.problemReporter().invalidUsageOfEnumDeclarations(enumDeclaration);
Lines 3146-3152 Link Here
3146
protected void consumeExpressionStatement() {
3324
protected void consumeExpressionStatement() {
3147
	// ExpressionStatement ::= StatementExpression ';'
3325
	// ExpressionStatement ::= StatementExpression ';'
3148
	this.expressionLengthPtr--;
3326
	this.expressionLengthPtr--;
3149
	pushOnAstStack(this.expressionStack[this.expressionPtr--]);
3327
	Expression expression = this.expressionStack[this.expressionPtr--];
3328
	expression.statementEnd = this.endStatementPosition;
3329
	pushOnAstStack(expression);
3150
}
3330
}
3151
protected void consumeFieldAccess(boolean isSuperAccess) {
3331
protected void consumeFieldAccess(boolean isSuperAccess) {
3152
	// FieldAccess ::= Primary '.' 'Identifier'
3332
	// FieldAccess ::= Primary '.' 'Identifier'
Lines 3290-3299 Link Here
3290
	this.listLength++; 	
3470
	this.listLength++; 	
3291
	
3471
	
3292
	if(isVarArgs) {
3472
	if(isVarArgs) {
3293
		if (options.sourceLevel < ClassFileConstants.JDK1_5 &&
3473
		if (!this.statementRecoveryActivated &&
3474
				options.sourceLevel < ClassFileConstants.JDK1_5 &&
3294
				this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
3475
				this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
3295
				this.problemReporter().invalidUsageOfVarargs(arg);
3476
				this.problemReporter().invalidUsageOfVarargs(arg);
3296
		} else if (extendedDimensions > 0) {
3477
		} else if (!this.statementRecoveryActivated &&
3478
				extendedDimensions > 0) {
3297
			this.problemReporter().illegalExtendedDimensions(arg);
3479
			this.problemReporter().illegalExtendedDimensions(arg);
3298
		}
3480
		}
3299
	}
3481
	}
Lines 3570-3576 Link Here
3570
protected void consumeInvalidAnnotationTypeDeclaration() {
3752
protected void consumeInvalidAnnotationTypeDeclaration() {
3571
	// BlockStatement ::= AnnotationTypeDeclaration
3753
	// BlockStatement ::= AnnotationTypeDeclaration
3572
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
3754
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
3573
	problemReporter().illegalLocalTypeDeclaration(typeDecl);
3755
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
3574
	// remove the ast node created in interface header
3756
	// remove the ast node created in interface header
3575
	this.astPtr--;
3757
	this.astPtr--;
3576
	pushOnAstLengthStack(-1);
3758
	pushOnAstLengthStack(-1);
Lines 3623-3629 Link Here
3623
	// BlockStatement ::= InvalidInterfaceDeclaration
3805
	// BlockStatement ::= InvalidInterfaceDeclaration
3624
	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
3806
	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
3625
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
3807
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
3626
	problemReporter().illegalLocalTypeDeclaration(typeDecl);
3808
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
3627
	// remove the ast node created in interface header
3809
	// remove the ast node created in interface header
3628
	this.astPtr--;
3810
	this.astPtr--;
3629
	pushOnAstLengthStack(-1);
3811
	pushOnAstLengthStack(-1);
Lines 3632-3638 Link Here
3632
protected void consumeInvalidEnumDeclaration() {
3814
protected void consumeInvalidEnumDeclaration() {
3633
	// BlockStatement ::= EnumDeclaration
3815
	// BlockStatement ::= EnumDeclaration
3634
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
3816
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
3635
	problemReporter().illegalLocalTypeDeclaration(typeDecl);
3817
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
3636
	// remove the ast node created in interface header
3818
	// remove the ast node created in interface header
3637
	this.astPtr--;
3819
	this.astPtr--;
3638
	pushOnAstLengthStack(-1);
3820
	pushOnAstLengthStack(-1);
Lines 3668-3674 Link Here
3668
	md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
3850
	md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
3669
3851
3670
	// report the problem and continue the parsing - narrowing the problem onto the method
3852
	// report the problem and continue the parsing - narrowing the problem onto the method
3671
	problemReporter().abstractMethodNeedingNoBody(md);
3853
	if(!this.statementRecoveryActivated) problemReporter().abstractMethodNeedingNoBody(md);
3672
}
3854
}
3673
protected void consumeLabel() {
3855
protected void consumeLabel() {
3674
	// Do nothing
3856
	// Do nothing
Lines 3728-3734 Link Here
3728
	markerAnnotation = new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]);
3910
	markerAnnotation = new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]);
3729
	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
3911
	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
3730
	pushOnExpressionStack(markerAnnotation);
3912
	pushOnExpressionStack(markerAnnotation);
3731
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
3913
	if(!this.statementRecoveryActivated &&
3914
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
3732
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
3915
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
3733
		this.problemReporter().invalidUsageOfAnnotation(markerAnnotation);
3916
		this.problemReporter().invalidUsageOfAnnotation(markerAnnotation);
3734
	}
3917
	}
Lines 4244-4250 Link Here
4244
		annotationRecoveryCheckPoint(normalAnnotation.sourceStart, normalAnnotation.declarationSourceEnd);
4427
		annotationRecoveryCheckPoint(normalAnnotation.sourceStart, normalAnnotation.declarationSourceEnd);
4245
	}
4428
	}
4246
	
4429
	
4247
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
4430
	if(!this.statementRecoveryActivated &&
4431
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
4248
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
4432
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
4249
		this.problemReporter().invalidUsageOfAnnotation(normalAnnotation);
4433
		this.problemReporter().invalidUsageOfAnnotation(normalAnnotation);
4250
	}
4434
	}
Lines 4261-4267 Link Here
4261
	this.expressionLengthPtr--;
4445
	this.expressionLengthPtr--;
4262
}
4446
}
4263
protected void consumeOnlyTypeArguments() {
4447
protected void consumeOnlyTypeArguments() {
4264
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
4448
	if(!this.statementRecoveryActivated &&
4449
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
4265
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
4450
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
4266
		int length = this.genericsLengthStack[this.genericsLengthPtr];
4451
		int length = this.genericsLengthStack[this.genericsLengthPtr];
4267
		this.problemReporter().invalidUsageOfTypeArguments(
4452
		this.problemReporter().invalidUsageOfTypeArguments(
Lines 6259-6265 Link Here
6259
		annotationRecoveryCheckPoint(singleMemberAnnotation.sourceStart, singleMemberAnnotation.declarationSourceEnd);
6444
		annotationRecoveryCheckPoint(singleMemberAnnotation.sourceStart, singleMemberAnnotation.declarationSourceEnd);
6260
	}
6445
	}
6261
	
6446
	
6262
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
6447
	if(!this.statementRecoveryActivated &&
6448
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
6263
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6449
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6264
		this.problemReporter().invalidUsageOfAnnotation(singleMemberAnnotation);
6450
		this.problemReporter().invalidUsageOfAnnotation(singleMemberAnnotation);
6265
	}
6451
	}
Lines 6291-6297 Link Here
6291
	//this.endPosition is just before the ;
6477
	//this.endPosition is just before the ;
6292
	impt.declarationSourceStart = this.intStack[this.intPtr--];
6478
	impt.declarationSourceStart = this.intStack[this.intPtr--];
6293
6479
6294
	if(this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
6480
	if(!this.statementRecoveryActivated &&
6481
			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
6295
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6482
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6296
		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
6483
		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
6297
		this.problemReporter().invalidUsageOfStaticImports(impt);
6484
		this.problemReporter().invalidUsageOfStaticImports(impt);
Lines 6660-6666 Link Here
6660
	//this.endPosition is just before the ;
6847
	//this.endPosition is just before the ;
6661
	impt.declarationSourceStart = this.intStack[this.intPtr--];
6848
	impt.declarationSourceStart = this.intStack[this.intPtr--];
6662
6849
6663
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
6850
	if(!this.statementRecoveryActivated &&
6851
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
6664
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6852
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6665
		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
6853
		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
6666
		this.problemReporter().invalidUsageOfStaticImports(impt);
6854
		this.problemReporter().invalidUsageOfStaticImports(impt);
Lines 6762-6773 Link Here
6762
			if (this.scanner.useAssertAsAnIndentifier  &&
6950
			if (this.scanner.useAssertAsAnIndentifier  &&
6763
					this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6951
					this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6764
				long positions = this.identifierPositionStack[this.identifierPtr];
6952
				long positions = this.identifierPositionStack[this.identifierPtr];
6765
				problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
6953
				if(!this.statementRecoveryActivated) problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
6766
			}
6954
			}
6767
			if (this.scanner.useEnumAsAnIndentifier  &&
6955
			if (this.scanner.useEnumAsAnIndentifier  &&
6768
					this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6956
					this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
6769
				long positions = this.identifierPositionStack[this.identifierPtr];
6957
				long positions = this.identifierPositionStack[this.identifierPtr];
6770
				problemReporter().useEnumAsAnIdentifier((int) (positions >>> 32), (int) positions);
6958
				if(!this.statementRecoveryActivated) problemReporter().useEnumAsAnIdentifier((int) (positions >>> 32), (int) positions);
6771
			}
6959
			}
6772
			break;
6960
			break;
6773
		case TokenNameinterface :
6961
		case TokenNameinterface :
Lines 7091-7097 Link Here
7091
	concatGenericsLists();
7279
	concatGenericsLists();
7092
	intPtr--;
7280
	intPtr--;
7093
7281
7094
	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
7282
	if(!this.statementRecoveryActivated &&
7283
			options.sourceLevel < ClassFileConstants.JDK1_5 &&
7095
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
7284
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
7096
		int length = this.genericsLengthStack[this.genericsLengthPtr];
7285
		int length = this.genericsLengthStack[this.genericsLengthPtr];
7097
		this.problemReporter().invalidUsageOfTypeArguments(
7286
		this.problemReporter().invalidUsageOfTypeArguments(
Lines 7202-7208 Link Here
7202
	}
7391
	}
7203
	
7392
	
7204
	
7393
	
7205
	if(options.sourceLevel < ClassFileConstants.JDK1_5&&
7394
	if(!this.statementRecoveryActivated &&
7395
			options.sourceLevel < ClassFileConstants.JDK1_5&&
7206
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
7396
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
7207
		int length = this.genericsLengthStack[this.genericsLengthPtr];
7397
		int length = this.genericsLengthStack[this.genericsLengthPtr];
7208
		this.problemReporter().invalidUsageOfTypeParameters(
7398
		this.problemReporter().invalidUsageOfTypeParameters(
Lines 7298-7304 Link Here
7298
		if (!post) {
7488
		if (!post) {
7299
			this.intPtr--;
7489
			this.intPtr--;
7300
		}
7490
		}
7301
		problemReporter().invalidUnaryExpression(leftHandSide);
7491
		if(!this.statementRecoveryActivated) problemReporter().invalidUnaryExpression(leftHandSide);
7302
	}
7492
	}
7303
}
7493
}
7304
protected void consumeVariableDeclarators() {
7494
protected void consumeVariableDeclarators() {
Lines 7678-7691 Link Here
7678
7868
7679
	this.lastAct = act;
7869
	this.lastAct = act;
7680
7870
7681
	if (this.currentElement != null){
7871
	if(this.statementRecoveryActivated) {
7682
		this.currentElement.topElement().updateParseTree();
7872
		RecoveredElement recoveredElement = this.buildInitialRecoveryState();
7873
		recoveredElement.topElement().updateParseTree();
7874
		if(this.hasError) this.resetStacks();
7875
	} else if (this.currentElement != null){
7683
		if (VERBOSE_RECOVERY){
7876
		if (VERBOSE_RECOVERY){
7684
			System.out.print(Messages.parser_syntaxRecovery); 
7877
			System.out.print(Messages.parser_syntaxRecovery); 
7685
			System.out.println("--------------------------");		 //$NON-NLS-1$
7878
			System.out.println("--------------------------");		 //$NON-NLS-1$
7686
			System.out.println(this.compilationUnit);		
7879
			System.out.println(this.compilationUnit);		
7687
			System.out.println("----------------------------------"); //$NON-NLS-1$
7880
			System.out.println("----------------------------------"); //$NON-NLS-1$
7688
		}
7881
		}
7882
		this.currentElement.topElement().updateParseTree();
7689
	} else {
7883
	} else {
7690
		if (this.diet & VERBOSE_RECOVERY){
7884
		if (this.diet & VERBOSE_RECOVERY){
7691
			System.out.print(Messages.parser_regularParse); 
7885
			System.out.print(Messages.parser_regularParse); 
Lines 7696-7702 Link Here
7696
	}
7890
	}
7697
	persistLineSeparatorPositions();
7891
	persistLineSeparatorPositions();
7698
	for (int i = 0; i < this.scanner.foundTaskCount; i++){
7892
	for (int i = 0; i < this.scanner.foundTaskCount; i++){
7699
		problemReporter().task(
7893
		if(!this.statementRecoveryActivated) problemReporter().task(
7700
			new String(this.scanner.foundTaskTags[i]), 
7894
			new String(this.scanner.foundTaskTags[i]), 
7701
			new String(this.scanner.foundTaskMessages[i]),
7895
			new String(this.scanner.foundTaskMessages[i]),
7702
			this.scanner.foundTaskPriorities[i] == null ? null : new String(this.scanner.foundTaskPriorities[i]), 
7896
			this.scanner.foundTaskPriorities[i] == null ? null : new String(this.scanner.foundTaskPriorities[i]), 
Lines 8187-8193 Link Here
8187
	ArrayInitializer arrayInitializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
8381
	ArrayInitializer arrayInitializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
8188
	this.expressionLengthPtr -- ;
8382
	this.expressionLengthPtr -- ;
8189
	// report a syntax error and abort parsing
8383
	// report a syntax error and abort parsing
8190
	problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd); 	
8384
	if(!this.statementRecoveryActivated) problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd); 	
8191
}
8385
}
8192
public void initialize() {
8386
public void initialize() {
8193
	this.initialize(false);
8387
	this.initialize(false);
Lines 8281-8286 Link Here
8281
	if (this.diet && (this.dietInt == 0))
8475
	if (this.diet && (this.dietInt == 0))
8282
		this.scanner.diet = true;
8476
		this.scanner.diet = true;
8283
}
8477
}
8478
private void jumpOverType(){
8479
	if (this.recoveredTypes != null && this.nextTypeStart > -1 && this.nextTypeStart < this.scanner.currentPosition) {
8480
		TypeDeclaration typeDeclaration = this.recoveredTypes[this.recoveredTypePtr];
8481
		boolean isAnonymous = typeDeclaration.allocation != null;
8482
		
8483
		int end = this.scanner.eofPosition;
8484
		this.scanner.resetTo(typeDeclaration.declarationSourceEnd + 1, end  - 1);
8485
		if(!isAnonymous) {
8486
			pushOnAstStack(typeDeclaration);
8487
			if(this.astLengthPtr > 0) {
8488
				concatNodeLists();
8489
			}
8490
			
8491
			if(this.currentElement != null) {
8492
				this.currentElement = this.currentElement.add(typeDeclaration, 0);
8493
			}
8494
			
8495
			try {
8496
				this.currentToken = this.scanner.getNextToken();
8497
			} catch(InvalidInputException e){
8498
				if (!this.hasReportedError){
8499
					this.problemReporter().scannerError(this, e.getMessage());
8500
					this.hasReportedError = true;
8501
				}
8502
				this.lastCheckPoint = this.scanner.currentPosition;
8503
			}
8504
		} else {
8505
			if(this.astPtr > -1 && this.astStack[this.astPtr] instanceof TypeDeclaration) {
8506
				this.astStack[astPtr] = typeDeclaration;
8507
				this.expressionStack[this.expressionPtr] = typeDeclaration.allocation;
8508
			}
8509
			this.currentToken = TokenNameRBRACE;
8510
		}
8511
		
8512
		if(++this.recoveredTypePtr < this.recoveredTypes.length) {
8513
			TypeDeclaration nextTypeDeclaration = this.recoveredTypes[this.recoveredTypePtr];
8514
			this.nextTypeStart =
8515
				nextTypeDeclaration.allocation == null
8516
					? nextTypeDeclaration.declarationSourceStart
8517
							: nextTypeDeclaration.bodyStart;
8518
		} else {
8519
			this.nextTypeStart = Integer.MAX_VALUE;
8520
		}
8521
	}
8522
}
8284
protected void markEnclosingMemberWithLocalType() {
8523
protected void markEnclosingMemberWithLocalType() {
8285
	if (this.currentElement != null) return; // this is already done in the recovery code
8524
	if (this.currentElement != null) return; // this is already done in the recovery code
8286
	for (int i = this.astPtr; i >= 0; i--) {
8525
	for (int i = this.astPtr; i >= 0; i--) {
Lines 8485-8490 Link Here
8485
protected void parse() {
8724
protected void parse() {
8486
	if (DEBUG) System.out.println("-- ENTER INSIDE PARSE METHOD --");  //$NON-NLS-1$
8725
	if (DEBUG) System.out.println("-- ENTER INSIDE PARSE METHOD --");  //$NON-NLS-1$
8487
	boolean isDietParse = this.diet;
8726
	boolean isDietParse = this.diet;
8727
	boolean jumpOverTypeAfterReduce = false;
8488
	int oldFirstToken = getFirstToken();
8728
	int oldFirstToken = getFirstToken();
8489
	this.hasError = false;
8729
	this.hasError = false;
8490
	
8730
	
Lines 8533-8539 Link Here
8533
				}
8773
				}
8534
				this.lastCheckPoint = this.scanner.currentPosition;
8774
				this.lastCheckPoint = this.scanner.currentPosition;
8535
				this.restartRecovery = true;
8775
				this.restartRecovery = true;
8536
			}					
8776
			}				
8777
			if(this.statementRecoveryActivated) {
8778
				jumpOverTypeAfterReduce = true;
8779
			}
8537
			act -= ERROR_ACTION;
8780
			act -= ERROR_ACTION;
8538
			
8781
			
8539
		} else {
8782
		} else {
Lines 8550-8555 Link Here
8550
					this.lastCheckPoint = this.scanner.currentPosition;
8793
					this.lastCheckPoint = this.scanner.currentPosition;
8551
					this.restartRecovery = true;
8794
					this.restartRecovery = true;
8552
				}					
8795
				}					
8796
				if(this.statementRecoveryActivated) {
8797
					this.jumpOverType();
8798
				}
8553
				continue ProcessTerminals;
8799
				continue ProcessTerminals;
8554
			}
8800
			}
8555
			break ProcessTerminals;
8801
			break ProcessTerminals;
Lines 8560-8565 Link Here
8560
			consumeRule(act);
8806
			consumeRule(act);
8561
			this.stateStackTop -= (rhs[act] - 1);
8807
			this.stateStackTop -= (rhs[act] - 1);
8562
			act = ntAction(this.stack[this.stateStackTop], lhs[act]);
8808
			act = ntAction(this.stack[this.stateStackTop], lhs[act]);
8809
			if(this.statementRecoveryActivated && act > NUM_RULES) {
8810
				if(jumpOverTypeAfterReduce) {
8811
					this.jumpOverType();
8812
					jumpOverTypeAfterReduce = false;
8813
				}
8814
			}
8563
		} while (act <= NUM_RULES);
8815
		} while (act <= NUM_RULES);
8564
	}
8816
	}
8565
	endParse(act);
8817
	endParse(act);
Lines 8568-8577 Link Here
8568
	if (tags != null) {
8820
	if (tags != null) {
8569
		this.compilationUnit.nlsTags = tags;
8821
		this.compilationUnit.nlsTags = tags;
8570
	}
8822
	}
8823
	
8571
	this.scanner.checkNonExternalizedStringLiterals = false;
8824
	this.scanner.checkNonExternalizedStringLiterals = false;
8572
	if (this.reportSyntaxErrorIsRequired && this.hasError) {
8825
	if (this.reportSyntaxErrorIsRequired && this.hasError && !this.statementRecoveryActivated) {
8573
		reportSyntaxErrors(isDietParse, oldFirstToken);
8826
		if(!this.options.performStatementsRecovery) {
8574
	}	
8827
			reportSyntaxErrors(isDietParse, oldFirstToken);
8828
		} else {
8829
			RecoveryScannerData data = this.referenceContext.compilationResult().recoveryScannerData;
8830
			
8831
			if(this.recoveryScanner == null) {
8832
				this.recoveryScanner = new RecoveryScanner(this.scanner, data);
8833
			} else {
8834
				this.recoveryScanner.setData(data);
8835
			}
8836
			
8837
			this.recoveryScanner.setSource(scanner.source);
8838
			this.recoveryScanner.lineEnds = this.scanner.lineEnds;
8839
			this.recoveryScanner.linePtr = this.scanner.linePtr;
8840
			
8841
			reportSyntaxErrors(isDietParse, oldFirstToken);
8842
			
8843
			if(data == null) {
8844
				this.referenceContext.compilationResult().recoveryScannerData =
8845
					this.recoveryScanner.getData();
8846
			}
8847
			
8848
			if (this.methodRecoveryActivated) {
8849
				this.methodRecoveryActivated = false;
8850
				this.recoverStatements();
8851
				this.methodRecoveryActivated = true;
8852
8853
				this.lastAct = ERROR_ACTION;
8854
			}
8855
		}
8856
	}
8857
	
8575
	if (DEBUG) System.out.println("-- EXIT FROM PARSE METHOD --");  //$NON-NLS-1$
8858
	if (DEBUG) System.out.println("-- EXIT FROM PARSE METHOD --");  //$NON-NLS-1$
8576
}
8859
}
8577
public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
8860
public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
Lines 8583-8588 Link Here
8583
8866
8584
	//convert bugs into parse error
8867
	//convert bugs into parse error
8585
8868
8869
	boolean oldMethodRecoveryActivated = this.methodRecoveryActivated;
8870
	if(this.options.performStatementsRecovery) {
8871
		this.methodRecoveryActivated = true;
8872
	}
8873
	
8586
	initialize();
8874
	initialize();
8587
	goForBlockStatementsopt();
8875
	goForBlockStatementsopt();
8588
	if (recordLineSeparator) {
8876
	if (recordLineSeparator) {
Lines 8601-8606 Link Here
8601
		this.lastAct = ERROR_ACTION;
8889
		this.lastAct = ERROR_ACTION;
8602
	} finally {
8890
	} finally {
8603
		this.nestedMethod[this.nestedType]--;
8891
		this.nestedMethod[this.nestedType]--;
8892
		if(this.options.performStatementsRecovery) {
8893
			this.methodRecoveryActivated = oldMethodRecoveryActivated;
8894
		}
8604
	}
8895
	}
8605
8896
8606
	checkNonNLSAfterBodyEnd(cd.declarationSourceEnd);
8897
	checkNonNLSAfterBodyEnd(cd.declarationSourceEnd);
Lines 8613-8619 Link Here
8613
	//statements
8904
	//statements
8614
	cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
8905
	cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
8615
	int length;
8906
	int length;
8616
	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
8907
	if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) != 0) {
8617
		this.astPtr -= length;
8908
		this.astPtr -= length;
8618
		if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
8909
		if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
8619
			//avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
8910
			//avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
Lines 8747-8752 Link Here
8747
9038
8748
	//convert bugs into parse error
9039
	//convert bugs into parse error
8749
9040
9041
	boolean oldMethodRecoveryActivated = this.methodRecoveryActivated;
9042
	if(this.options.performStatementsRecovery) {
9043
		this.methodRecoveryActivated = true;
9044
	}
9045
	
8750
	initialize();
9046
	initialize();
8751
	goForBlockStatementsopt();
9047
	goForBlockStatementsopt();
8752
	this.nestedMethod[this.nestedType]++;
9048
	this.nestedMethod[this.nestedType]++;
Lines 8762-8767 Link Here
8762
		this.lastAct = ERROR_ACTION;
9058
		this.lastAct = ERROR_ACTION;
8763
	} finally {
9059
	} finally {
8764
		this.nestedMethod[this.nestedType]--;
9060
		this.nestedMethod[this.nestedType]--;
9061
		if(this.options.performStatementsRecovery) {
9062
			this.methodRecoveryActivated = oldMethodRecoveryActivated;
9063
		}
8765
	}
9064
	}
8766
9065
8767
	checkNonNLSAfterBodyEnd(initializer.declarationSourceEnd);
9066
	checkNonNLSAfterBodyEnd(initializer.declarationSourceEnd);
Lines 8773-8779 Link Here
8773
	//refill statements
9072
	//refill statements
8774
	initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
9073
	initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
8775
	int length;
9074
	int length;
8776
	if ((length = this.astLengthStack[this.astLengthPtr--]) > 0) {
9075
	if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > 0) {
8777
		System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length); 
9076
		System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length); 
8778
	} else {
9077
	} else {
8779
		// check whether this block at least contains some comment in it
9078
		// check whether this block at least contains some comment in it
Lines 8801-8806 Link Here
8801
	if ((md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0)
9100
	if ((md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0)
8802
		return;
9101
		return;
8803
9102
9103
	boolean oldMethodRecoveryActivated = this.methodRecoveryActivated;
9104
	if(this.options.performStatementsRecovery) {
9105
		this.methodRecoveryActivated = true;
9106
		this.rParenPos = md.sourceEnd;
9107
	}
8804
	initialize();
9108
	initialize();
8805
	goForBlockStatementsopt();
9109
	goForBlockStatementsopt();
8806
	this.nestedMethod[this.nestedType]++;
9110
	this.nestedMethod[this.nestedType]++;
Lines 8817-8822 Link Here
8817
		this.lastAct = ERROR_ACTION;
9121
		this.lastAct = ERROR_ACTION;
8818
	} finally {
9122
	} finally {
8819
		this.nestedMethod[this.nestedType]--;		
9123
		this.nestedMethod[this.nestedType]--;		
9124
		if(this.options.performStatementsRecovery) {
9125
			this.methodRecoveryActivated = oldMethodRecoveryActivated;
9126
		}
8820
	}
9127
	}
8821
9128
8822
	checkNonNLSAfterBodyEnd(md.declarationSourceEnd);
9129
	checkNonNLSAfterBodyEnd(md.declarationSourceEnd);
Lines 8828-8834 Link Here
8828
	//refill statements
9135
	//refill statements
8829
	md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
9136
	md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
8830
	int length;
9137
	int length;
8831
	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
9138
	if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) != 0) {
8832
		System.arraycopy(
9139
		System.arraycopy(
8833
			this.astStack, 
9140
			this.astStack, 
8834
			(this.astPtr -= length) + 1, 
9141
			(this.astPtr -= length) + 1, 
Lines 8871-8877 Link Here
8871
		return null;
9178
		return null;
8872
	}
9179
	}
8873
	int astLength;
9180
	int astLength;
8874
	if ((astLength = this.astLengthStack[this.astLengthPtr--]) != 0) {
9181
	if (astLengthPtr > -1 && (astLength = this.astLengthStack[this.astLengthPtr--]) != 0) {
8875
		ASTNode[] result = new ASTNode[astLength];
9182
		ASTNode[] result = new ASTNode[astLength];
8876
		this.astPtr -= astLength;
9183
		this.astPtr -= astLength;
8877
		System.arraycopy(this.astStack, this.astPtr + 1, result, 0, astLength);
9184
		System.arraycopy(this.astStack, this.astPtr + 1, result, 0, astLength);
Lines 8929-8939 Link Here
8929
9236
8930
	return this.expressionStack[this.expressionPtr];
9237
	return this.expressionStack[this.expressionPtr];
8931
}
9238
}
9239
public void parseStatements(ReferenceContext rc, int start, int end, TypeDeclaration[] types, CompilationUnitDeclaration unit) {
9240
	boolean oldStatementRecoveryEnabled = this.statementRecoveryActivated;
9241
	this.statementRecoveryActivated = true;
9242
	
9243
	initialize();
9244
	
9245
	goForBlockStatementsopt();
9246
	this.nestedMethod[this.nestedType]++;
9247
	pushOnRealBlockStack(0);
9248
	
9249
	pushOnAstLengthStack(0);
9250
9251
	this.referenceContext = rc;
9252
	this.compilationUnit = unit;
9253
	
9254
	if(types != null && types.length > 0) {
9255
		this.recoveredTypes = types;
9256
		this.recoveredTypePtr = 0;
9257
		this.nextTypeStart =
9258
			this.recoveredTypes[0].allocation == null
9259
				? this.recoveredTypes[0].declarationSourceStart
9260
						: this.recoveredTypes[0].bodyStart;
9261
	} else {
9262
		this.recoveredTypes = null;
9263
		this.recoveredTypePtr = -1;
9264
		this.nextTypeStart = -1;
9265
	}
9266
	
9267
	this.scanner.resetTo(start, end);
9268
	// reset the scanner to parser from { down to }
9269
	
9270
	this.lastCheckPoint = this.scanner.initialPosition;
9271
	
9272
	
9273
	this.stateStackTop = -1;
9274
		
9275
	try {
9276
		parse();
9277
	} catch (AbortCompilation ex) {
9278
		this.lastAct = ERROR_ACTION;
9279
	} finally {
9280
		this.nestedMethod[this.nestedType]--;	
9281
		this.recoveredTypes = null;
9282
		this.statementRecoveryActivated = oldStatementRecoveryEnabled;
9283
	}
9284
9285
	checkNonNLSAfterBodyEnd(end);
9286
}
8932
public void persistLineSeparatorPositions() {
9287
public void persistLineSeparatorPositions() {
8933
	if (this.scanner.recordLineSeparator) {
9288
	if (this.scanner.recordLineSeparator) {
8934
		this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
9289
		this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
8935
	}
9290
	}
8936
}
9291
}
9292
/*
9293
 * Prepares the state of the parser to go for BlockStatements.
9294
 */
9295
protected void prepareForBlockStatements() {
9296
	this.nestedMethod[this.nestedType = 0] = 1;
9297
	this.variablesCounter[this.nestedType] = 0;
9298
	this.realBlockStack[this.realBlockPtr = 1] = 0;
9299
}
8937
/**
9300
/**
8938
 * Returns this parser's problem reporter initialized with its reference context.
9301
 * Returns this parser's problem reporter initialized with its reference context.
8939
 * Also it is assumed that a problem is going to be reported, so initializes
9302
 * Also it is assumed that a problem is going to be reported, so initializes
Lines 9121-9126 Link Here
9121
	}
9484
	}
9122
	this.realBlockStack[this.realBlockPtr] = i;
9485
	this.realBlockStack[this.realBlockPtr] = i;
9123
}
9486
}
9487
protected void recoverStatements() {
9488
	class MethodVisitor extends ASTVisitor {
9489
		public ASTVisitor typeVisitor;
9490
		
9491
		TypeDeclaration enclosingType; // used only for initializer
9492
		
9493
		TypeDeclaration[] types = new TypeDeclaration[0];
9494
		int typePtr = -1;
9495
		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
9496
			typePtr = -1;
9497
			return true;
9498
		}
9499
		public boolean visit(Initializer initializer, MethodScope scope) {
9500
			typePtr = -1;
9501
			return true;
9502
		}
9503
		public boolean visit(MethodDeclaration methodDeclaration,ClassScope scope) {
9504
			typePtr = -1;
9505
			return true;
9506
		}
9507
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
9508
			return this.visit(typeDeclaration);
9509
		}
9510
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
9511
			return this.visit(typeDeclaration);
9512
		}
9513
		private boolean visit(TypeDeclaration typeDeclaration) {
9514
			if(this.types.length <= ++this.typePtr) {
9515
				int length = this.typePtr;
9516
				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
9517
			}
9518
			this.types[this.typePtr] = typeDeclaration;
9519
			return false;
9520
		}
9521
		public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
9522
			this.endVisitMethod(constructorDeclaration, scope);
9523
		}
9524
		public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
9525
			this.endVisitMethod(methodDeclaration, scope);
9526
		}
9527
		private void endVisitMethod(AbstractMethodDeclaration methodDeclaration, ClassScope scope) {
9528
			TypeDeclaration[] foundTypes = null;
9529
			int length = 0;
9530
			if(this.typePtr > -1) {
9531
				length = this.typePtr + 1;
9532
				foundTypes = new TypeDeclaration[length];
9533
				System.arraycopy(this.types, 0, foundTypes, 0, length);
9534
			}
9535
			ReferenceContext oldContext = Parser.this.referenceContext;
9536
			Parser.this.recoveryScanner.resetTo(methodDeclaration.bodyStart, methodDeclaration.bodyEnd);
9537
			Scanner oldScanner = Parser.this.scanner;
9538
			Parser.this.scanner = Parser.this.recoveryScanner;
9539
			Parser.this.parseStatements(
9540
					methodDeclaration,
9541
					methodDeclaration.bodyStart,
9542
					methodDeclaration.bodyEnd,
9543
					foundTypes,
9544
					compilationUnit);
9545
			Parser.this.scanner = oldScanner;
9546
			Parser.this.referenceContext = oldContext;
9547
			
9548
			for (int i = 0; i < length; i++) {
9549
				foundTypes[i].traverse(typeVisitor, scope);
9550
			}
9551
		}
9552
		public void endVisit(Initializer initializer, MethodScope scope) {
9553
			TypeDeclaration[] foundTypes = null;
9554
			int length = 0;
9555
			if(this.typePtr > -1) {
9556
				length = this.typePtr + 1;
9557
				foundTypes = new TypeDeclaration[length];
9558
				System.arraycopy(this.types, 0, foundTypes, 0, length);
9559
			}
9560
			ReferenceContext oldContext = Parser.this.referenceContext;
9561
			Parser.this.recoveryScanner.resetTo(initializer.bodyStart, initializer.bodyEnd);
9562
			Scanner oldScanner = Parser.this.scanner;
9563
			Parser.this.scanner = Parser.this.recoveryScanner;
9564
			Parser.this.parseStatements(
9565
					this.enclosingType,
9566
					initializer.bodyStart,
9567
					initializer.bodyEnd,
9568
					foundTypes,
9569
					compilationUnit);
9570
			Parser.this.scanner = oldScanner;
9571
			Parser.this.referenceContext = oldContext;
9572
			
9573
			for (int i = 0; i < length; i++) {
9574
				foundTypes[i].traverse(typeVisitor, scope);
9575
			}
9576
		}
9577
	}
9578
	class TypeVisitor extends ASTVisitor {
9579
		public MethodVisitor methodVisitor;
9580
		
9581
		TypeDeclaration[] types = new TypeDeclaration[0];
9582
		int typePtr = -1;
9583
		
9584
		public void endVisit(TypeDeclaration typeDeclaration, BlockScope scope) {
9585
			endVisitType();
9586
		}
9587
		public void endVisit(TypeDeclaration typeDeclaration, ClassScope scope) {
9588
			endVisitType();
9589
		}
9590
		private void endVisitType() {
9591
			this.typePtr--;
9592
		}
9593
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
9594
			return this.visit(typeDeclaration);
9595
		}
9596
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
9597
			return this.visit(typeDeclaration);
9598
		}
9599
		private boolean visit(TypeDeclaration typeDeclaration) {
9600
			if(this.types.length <= ++this.typePtr) {
9601
				int length = this.typePtr;
9602
				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
9603
			}
9604
			this.types[this.typePtr] = typeDeclaration;
9605
			return true;
9606
		}
9607
		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
9608
			if(constructorDeclaration.isDefaultConstructor()) return false;
9609
			
9610
			constructorDeclaration.traverse(methodVisitor, scope);
9611
			return false;
9612
		}
9613
		public boolean visit(Initializer initializer, MethodScope scope) {
9614
			methodVisitor.enclosingType = this.types[typePtr];
9615
			initializer.traverse(methodVisitor, scope);
9616
			return false;
9617
		}
9618
		public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
9619
			methodDeclaration.traverse(methodVisitor, scope);
9620
			return false;
9621
		}
9622
	}
9623
	
9624
	MethodVisitor methodVisitor = new MethodVisitor();
9625
	TypeVisitor typeVisitor = new TypeVisitor();
9626
	methodVisitor.typeVisitor = typeVisitor;
9627
	typeVisitor.methodVisitor = methodVisitor;
9628
	
9629
	if(this.referenceContext instanceof AbstractMethodDeclaration) {
9630
		((AbstractMethodDeclaration)this.referenceContext).traverse(methodVisitor, (ClassScope)null);
9631
	} else if(this.referenceContext instanceof TypeDeclaration) {
9632
		TypeDeclaration typeContext = (TypeDeclaration)this.referenceContext;
9633
		
9634
		int length = typeContext.fields.length;
9635
		for (int i = 0; i < length; i++) {
9636
			final FieldDeclaration fieldDeclaration = typeContext.fields[i];
9637
			switch(fieldDeclaration.getKind()) {
9638
				case AbstractVariableDeclaration.INITIALIZER:
9639
					methodVisitor.enclosingType = typeContext;
9640
					((Initializer) fieldDeclaration).traverse(methodVisitor, (MethodScope)null);
9641
					break;
9642
			}
9643
		}
9644
	}
9645
}
9646
9124
public void recoveryExitFromVariable() {
9647
public void recoveryExitFromVariable() {
9125
	if(this.currentElement != null && this.currentElement.parent != null) {
9648
	if(this.currentElement != null && this.currentElement.parent != null) {
9126
		if(this.currentElement instanceof RecoveredLocalVariable) {
9649
		if(this.currentElement instanceof RecoveredLocalVariable) {
Lines 9202-9217 Link Here
9202
	int end = this.scanner.eofPosition <= Integer.MAX_VALUE ? this.scanner.eofPosition - 1 : this.scanner.eofPosition;
9725
	int end = this.scanner.eofPosition <= Integer.MAX_VALUE ? this.scanner.eofPosition - 1 : this.scanner.eofPosition;
9203
	if(isDietParse) {
9726
	if(isDietParse) {
9204
		TypeDeclaration[] types = this.compilationUnit.types;
9727
		TypeDeclaration[] types = this.compilationUnit.types;
9205
		
9206
		int[][] intervalToSkip = org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil.computeDietRange(types);
9728
		int[][] intervalToSkip = org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil.computeDietRange(types);
9207
		DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, intervalToSkip[0], intervalToSkip[1], intervalToSkip[2], this.options);
9729
		DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, intervalToSkip[0], intervalToSkip[1], intervalToSkip[2], this.options);
9208
		diagnoseParser.diagnoseParse();
9730
		diagnoseParser.diagnoseParse(false);
9209
		
9731
		
9210
		reportSyntaxErrorsForSkippedMethod(types);
9732
		reportSyntaxErrorsForSkippedMethod(types);
9211
		this.scanner.resetTo(start, end);
9733
		this.scanner.resetTo(start, end);
9212
	} else {
9734
	} else {
9213
		DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, this.options);
9735
		DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, this.options);
9214
		diagnoseParser.diagnoseParse();
9736
		diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
9215
	}
9737
	}
9216
}
9738
}
9217
private void reportSyntaxErrorsForSkippedMethod(TypeDeclaration[] types){
9739
private void reportSyntaxErrorsForSkippedMethod(TypeDeclaration[] types){
Lines 9229-9238 Link Here
9229
					if(method.errorInSignature) {
9751
					if(method.errorInSignature) {
9230
						if(method.isAnnotationMethod()) {
9752
						if(method.isAnnotationMethod()) {
9231
							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameQUESTION, method.declarationSourceStart, method.declarationSourceEnd, this.options);
9753
							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameQUESTION, method.declarationSourceStart, method.declarationSourceEnd, this.options);
9232
							diagnoseParser.diagnoseParse();
9754
							diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
9233
						} else {
9755
						} else {
9234
							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameDIVIDE, method.declarationSourceStart, method.declarationSourceEnd, this.options);
9756
							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameDIVIDE, method.declarationSourceStart, method.declarationSourceEnd, this.options);
9235
							diagnoseParser.diagnoseParse();
9757
							diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
9236
						}
9758
						}
9237
						
9759
						
9238
					}
9760
					}
Lines 9247-9253 Link Here
9247
						Initializer initializer = (Initializer)fields[j];
9769
						Initializer initializer = (Initializer)fields[j];
9248
						if(initializer.errorInSignature){
9770
						if(initializer.errorInSignature){
9249
							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameRIGHT_SHIFT, initializer.declarationSourceStart, initializer.declarationSourceEnd, this.options);
9771
							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameRIGHT_SHIFT, initializer.declarationSourceStart, initializer.declarationSourceEnd, this.options);
9250
							diagnoseParser.diagnoseParse();
9772
							diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
9251
						}
9773
						}
9252
					}
9774
					}
9253
				}
9775
				}
Lines 9292-9315 Link Here
9292
 * decide which grammar goal is activated.
9814
 * decide which grammar goal is activated.
9293
 */
9815
 */
9294
protected boolean resumeAfterRecovery() {
9816
protected boolean resumeAfterRecovery() {
9295
9817
	if(!this.methodRecoveryActivated && !this.statementRecoveryActivated) {
9296
	// reset internal stacks 
9818
		
9297
	this.resetStacks();
9819
		// reset internal stacks 
9298
	this.resetModifiers();
9820
		this.resetStacks();
9821
		this.resetModifiers();
9822
		
9823
		/* attempt to move checkpoint location */
9824
		if (!this.moveRecoveryCheckpoint()) {
9825
			return false;
9826
		}
9299
	
9827
	
9300
	/* attempt to move checkpoint location */
9828
		// only look for headers
9301
	if (!this.moveRecoveryCheckpoint()) {
9829
		if (this.referenceContext instanceof CompilationUnitDeclaration){
9830
			goForHeaders();
9831
			this.diet = true; // passed this point, will not consider method bodies
9832
			return true;
9833
		}
9834
		
9835
		// does not know how to restart
9302
		return false;
9836
		return false;
9303
	}
9837
	} else if(!this.statementRecoveryActivated) {
9304
9838
		
9305
	// only look for headers
9839
		// reset internal stacks 
9306
	if (this.referenceContext instanceof CompilationUnitDeclaration){
9840
		this.resetStacks();
9841
		this.resetModifiers();
9842
		
9843
		/* attempt to move checkpoint location */
9844
		if (!this.moveRecoveryCheckpoint()) {
9845
			return false;
9846
		}
9847
		
9848
		// only look for headers
9307
		goForHeaders();
9849
		goForHeaders();
9308
		this.diet = true; // passed this point, will not consider method bodies
9309
		return true;
9850
		return true;
9851
	} else {
9852
		return false;
9310
	}
9853
	}
9311
	// does not know how to restart
9312
	return false;
9313
}
9854
}
9314
protected boolean resumeOnSyntaxError() {
9855
protected boolean resumeOnSyntaxError() {
9315
	this.checkExternalizeStrings = false;
9856
	this.checkExternalizeStrings = false;
Lines 9335-9340 Link Here
9335
	/* attempt to reset state in order to resume to parse loop */
9876
	/* attempt to reset state in order to resume to parse loop */
9336
	return this.resumeAfterRecovery();
9877
	return this.resumeAfterRecovery();
9337
}
9878
}
9879
public void setStatementsRecovery(boolean enabled) {
9880
	this.options.performStatementsRecovery = enabled;
9881
}
9338
public String toString() {
9882
public String toString() {
9339
9883
9340
9884
(-)compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java (-1 / +1 lines)
Lines 207-213 Link Here
207
		}
207
		}
208
		return this.parent.add(typeDeclaration, bracketBalanceValue);
208
		return this.parent.add(typeDeclaration, bracketBalanceValue);
209
	}
209
	}
210
	if ((typeDeclaration.bits & ASTNode.IsLocalType) != 0){
210
	if ((typeDeclaration.bits & ASTNode.IsLocalType) != 0 || this.parser().methodRecoveryActivated || this.parser().statementRecoveryActivated){
211
		if (methodBody == null){
211
		if (methodBody == null){
212
			Block block = new Block(0);
212
			Block block = new Block(0);
213
			block.sourceStart = methodDeclaration.bodyStart;
213
			block.sourceStart = methodDeclaration.bodyStart;
(-)compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java (+9 lines)
Lines 106-111 Link Here
106
	this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));	
106
	this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));	
107
	return this.parent.add(typeDeclaration, bracketBalanceValue);
107
	return this.parent.add(typeDeclaration, bracketBalanceValue);
108
}
108
}
109
protected void addBlockStatement(RecoveredBlock recoveredBlock) {
110
	Block block = recoveredBlock.blockDeclaration;
111
	if(block.statements != null) {
112
		Statement[] statements = block.statements;
113
		for (int i = 0; i < statements.length; i++) {
114
			recoveredBlock.add(statements[i], 0);
115
		}
116
	}
117
}
109
/*
118
/*
110
 * Answer the depth of this element, considering the parent link.
119
 * Answer the depth of this element, considering the parent link.
111
 */
120
 */
(-)compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java (+5 lines)
Lines 33-38 Link Here
33
	super(block, parent, bracketBalance);
33
	super(block, parent, bracketBalance);
34
	this.blockDeclaration = block;
34
	this.blockDeclaration = block;
35
	this.foundOpeningBrace = true;
35
	this.foundOpeningBrace = true;
36
	
37
	this.preserveContent = this.parser().methodRecoveryActivated || this.parser().statementRecoveryActivated;
36
}
38
}
37
/*
39
/*
38
 * Record a nested block declaration 
40
 * Record a nested block declaration 
Lines 53-58 Link Here
53
		element.attach(this.pendingArgument);
55
		element.attach(this.pendingArgument);
54
		this.pendingArgument = null;
56
		this.pendingArgument = null;
55
	}
57
	}
58
	if(this.parser().statementRecoveryActivated) {
59
		this.addBlockStatement(element);
60
	}
56
	this.attach(element);
61
	this.attach(element);
57
	if (nestedBlockDeclaration.sourceEnd == 0) return element;
62
	if (nestedBlockDeclaration.sourceEnd == 0) return element;
58
	return this;	
63
	return this;	
(-)compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java (-1 / +1 lines)
Lines 410-416 Link Here
410
public int getCurrentTokenEndPosition(){
410
public int getCurrentTokenEndPosition(){
411
	return this.currentPosition - 1;
411
	return this.currentPosition - 1;
412
}
412
}
413
public final char[] getCurrentTokenSource() {
413
public char[] getCurrentTokenSource() {
414
	// Return the token REAL source (aka unicodes are precomputed)
414
	// Return the token REAL source (aka unicodes are precomputed)
415
415
416
	char[] result;
416
	char[] result;
(-)compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java (-1 / +16 lines)
Lines 57-62 Link Here
57
	if(this.foundOpeningBrace) {
57
	if(this.foundOpeningBrace) {
58
		this.bracketBalance++;
58
		this.bracketBalance++;
59
	}
59
	}
60
	
61
	this.preserveContent = this.parser().methodRecoveryActivated || this.parser().statementRecoveryActivated;
60
}
62
}
61
public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
63
public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
62
64
Lines 311-317 Link Here
311
	return updatedType;
313
	return updatedType;
312
}
314
}
313
public TypeDeclaration updatedTypeDeclaration(){
315
public TypeDeclaration updatedTypeDeclaration(){
314
316
	int lastEnd = typeDeclaration.bodyStart;
315
	/* update member types */
317
	/* update member types */
316
	if (memberTypeCount > 0){
318
	if (memberTypeCount > 0){
317
		int existingCount = typeDeclaration.memberTypes == null ? 0 : typeDeclaration.memberTypes.length;
319
		int existingCount = typeDeclaration.memberTypes == null ? 0 : typeDeclaration.memberTypes.length;
Lines 329-334 Link Here
329
			memberTypeDeclarations[existingCount + i] = memberTypes[i].updatedTypeDeclaration();
331
			memberTypeDeclarations[existingCount + i] = memberTypes[i].updatedTypeDeclaration();
330
		}
332
		}
331
		typeDeclaration.memberTypes = memberTypeDeclarations;
333
		typeDeclaration.memberTypes = memberTypeDeclarations;
334
		if(memberTypeDeclarations[memberTypeDeclarations.length - 1].declarationSourceEnd > lastEnd) {
335
			lastEnd = memberTypeDeclarations[memberTypeDeclarations.length - 1].declarationSourceEnd;
336
		}
332
	}
337
	}
333
	/* update fields */
338
	/* update fields */
334
	if (fieldCount > 0){
339
	if (fieldCount > 0){
Lines 347-352 Link Here
347
			fieldDeclarations[existingCount + i] = fields[i].updatedFieldDeclaration();
352
			fieldDeclarations[existingCount + i] = fields[i].updatedFieldDeclaration();
348
		}
353
		}
349
		typeDeclaration.fields = fieldDeclarations;
354
		typeDeclaration.fields = fieldDeclarations;
355
		if(fieldDeclarations[fieldDeclarations.length - 1].declarationSourceEnd > lastEnd) {
356
			lastEnd = fieldDeclarations[fieldDeclarations.length - 1].declarationSourceEnd;
357
		}
350
	}
358
	}
351
	/* update methods */
359
	/* update methods */
352
	int existingCount = typeDeclaration.methods == null ? 0 : typeDeclaration.methods.length;
360
	int existingCount = typeDeclaration.methods == null ? 0 : typeDeclaration.methods.length;
Lines 374-379 Link Here
374
			methodDeclarations[existingCount + i] = updatedMethod;			
382
			methodDeclarations[existingCount + i] = updatedMethod;			
375
		}
383
		}
376
		typeDeclaration.methods = methodDeclarations;
384
		typeDeclaration.methods = methodDeclarations;
385
		if(methodDeclarations[methodDeclarations.length - 1].declarationSourceEnd > lastEnd) {
386
			lastEnd = methodDeclarations[methodDeclarations.length - 1].declarationSourceEnd;
387
		}
377
		if (hasAbstractMethods) typeDeclaration.bits |= ASTNode.HasAbstractMethods;
388
		if (hasAbstractMethods) typeDeclaration.bits |= ASTNode.HasAbstractMethods;
378
		hasConstructor = typeDeclaration.checkConstructors(this.parser());
389
		hasConstructor = typeDeclaration.checkConstructors(this.parser());
379
	} else {
390
	} else {
Lines 428-433 Link Here
428
	} else if (parent instanceof RecoveredMethod){
439
	} else if (parent instanceof RecoveredMethod){
429
		typeDeclaration.bits |= ASTNode.IsLocalType;
440
		typeDeclaration.bits |= ASTNode.IsLocalType;
430
	}
441
	}
442
	if(typeDeclaration.declarationSourceEnd == 0) {
443
		typeDeclaration.declarationSourceEnd = lastEnd;
444
		typeDeclaration.bodyEnd = lastEnd;
445
	}
431
	return typeDeclaration;
446
	return typeDeclaration;
432
}
447
}
433
/*
448
/*
(-)grammar/java_1_5.g (-3 / +16 lines)
Lines 28-38 Link Here
28
28
29
29
30
$readableName 
30
$readableName 
31
/.1#$rule_number=./
31
/.1#$rule_number#./
32
$compliance
32
$compliance
33
/.2#$rule_number=./
33
/.2#$rule_number#./
34
$recovery
34
$recovery
35
/.2#$rule_number= recovery./
35
/.2#$rule_number# recovery./
36
$recovery_template
37
/.3#$rule_number#./
38
$no_statements_recovery
39
/.4#$rule_number# 1./
36
-- here it starts really ------------------------------------------
40
-- here it starts really ------------------------------------------
37
$Terminals
41
$Terminals
38
42
Lines 483-488 Link Here
483
487
484
ClassBody ::= '{' ClassBodyDeclarationsopt '}'
488
ClassBody ::= '{' ClassBodyDeclarationsopt '}'
485
/:$readableName ClassBody:/
489
/:$readableName ClassBody:/
490
/:$no_statements_recovery:/
486
491
487
ClassBodyDeclarations ::= ClassBodyDeclaration
492
ClassBodyDeclarations ::= ClassBodyDeclaration
488
ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
493
ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
Lines 612-617 Link Here
612
MethodHeaderRightParen ::= ')'
617
MethodHeaderRightParen ::= ')'
613
/.$putCase consumeMethodHeaderRightParen(); $break ./
618
/.$putCase consumeMethodHeaderRightParen(); $break ./
614
/:$readableName ):/
619
/:$readableName ):/
620
/:$recovery_template ):/
615
621
616
MethodHeaderExtendedDims ::= Dimsopt
622
MethodHeaderExtendedDims ::= Dimsopt
617
/.$putCase consumeMethodHeaderExtendedDims(); $break ./
623
/.$putCase consumeMethodHeaderExtendedDims(); $break ./
Lines 656-661 Link Here
656
MethodBody ::= NestedMethod '{' BlockStatementsopt '}' 
662
MethodBody ::= NestedMethod '{' BlockStatementsopt '}' 
657
/.$putCase consumeMethodBody(); $break ./
663
/.$putCase consumeMethodBody(); $break ./
658
/:$readableName MethodBody:/
664
/:$readableName MethodBody:/
665
/:$no_statements_recovery:/
659
666
660
NestedMethod ::= $empty
667
NestedMethod ::= $empty
661
/.$putCase consumeNestedMethod(); $break ./
668
/.$putCase consumeNestedMethod(); $break ./
Lines 810-815 Link Here
810
ArrayInitializer ::= '{' PushLeftBrace VariableInitializers , '}'
817
ArrayInitializer ::= '{' PushLeftBrace VariableInitializers , '}'
811
/.$putCase consumeArrayInitializer(); $break ./
818
/.$putCase consumeArrayInitializer(); $break ./
812
/:$readableName ArrayInitializer:/
819
/:$readableName ArrayInitializer:/
820
/:$recovery_template Identifier:/
813
821
814
VariableInitializers ::= VariableInitializer
822
VariableInitializers ::= VariableInitializer
815
VariableInitializers ::= VariableInitializers ',' VariableInitializer
823
VariableInitializers ::= VariableInitializers ',' VariableInitializer
Lines 1087-1095 Link Here
1087
PushLPAREN ::= '('
1095
PushLPAREN ::= '('
1088
/.$putCase consumeLeftParen(); $break ./
1096
/.$putCase consumeLeftParen(); $break ./
1089
/:$readableName (:/
1097
/:$readableName (:/
1098
/:$recovery_template (:/
1090
PushRPAREN ::= ')'
1099
PushRPAREN ::= ')'
1091
/.$putCase consumeRightParen(); $break ./
1100
/.$putCase consumeRightParen(); $break ./
1092
/:$readableName ):/
1101
/:$readableName ):/
1102
/:$recovery_template ):/
1093
1103
1094
Primary -> PrimaryNoNewArray
1104
Primary -> PrimaryNoNewArray
1095
Primary -> ArrayCreationWithArrayInitializer
1105
Primary -> ArrayCreationWithArrayInitializer
Lines 1174-1179 Link Here
1174
/.$putCase consumeClassBodyopt(); $break ./
1184
/.$putCase consumeClassBodyopt(); $break ./
1175
ClassBodyopt ::= EnterAnonymousClassBody ClassBody
1185
ClassBodyopt ::= EnterAnonymousClassBody ClassBody
1176
/:$readableName ClassBody:/
1186
/:$readableName ClassBody:/
1187
/:$no_statements_recovery:/
1177
1188
1178
EnterAnonymousClassBody ::= $empty
1189
EnterAnonymousClassBody ::= $empty
1179
/.$putCase consumeEnterAnonymousClassBody(); $break ./
1190
/.$putCase consumeEnterAnonymousClassBody(); $break ./
Lines 1448-1456 Link Here
1448
AssignmentOperator ::= '|='
1459
AssignmentOperator ::= '|='
1449
/.$putCase consumeAssignmentOperator(OR); $break ./
1460
/.$putCase consumeAssignmentOperator(OR); $break ./
1450
/:$readableName AssignmentOperator:/
1461
/:$readableName AssignmentOperator:/
1462
/:$recovery_template =:/
1451
1463
1452
Expression -> AssignmentExpression
1464
Expression -> AssignmentExpression
1453
/:$readableName Expression:/
1465
/:$readableName Expression:/
1466
/:$recovery_template Identifier:/
1454
1467
1455
-- The following rules are for optional nonterminals.
1468
-- The following rules are for optional nonterminals.
1456
--
1469
--
(-)model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java (-4 / +6 lines)
Lines 62-68 Link Here
62
					new DefaultProblemFactory(Locale.getDefault()));
62
					new DefaultProblemFactory(Locale.getDefault()));
63
					
63
					
64
		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
64
		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
65
65
		parser.setStatementsRecovery(false);
66
		
66
		ICompilationUnit sourceUnit = 
67
		ICompilationUnit sourceUnit = 
67
			new CompilationUnit(
68
			new CompilationUnit(
68
				source, 
69
				source, 
Lines 158-168 Link Here
158
		return result;
159
		return result;
159
	}
160
	}
160
161
161
	public ConstructorDeclaration parseStatements(char[] source, Map settings, boolean recordParsingInformation) {
162
	public ConstructorDeclaration parseStatements(char[] source, Map settings, boolean recordParsingInformation, boolean enabledStatementRecovery) {
162
		return parseStatements(source, 0, source.length, settings, recordParsingInformation);
163
		return parseStatements(source, 0, source.length, settings, recordParsingInformation, enabledStatementRecovery);
163
	}
164
	}
164
	
165
	
165
	public ConstructorDeclaration parseStatements(char[] source, int offset, int length, Map settings, boolean recordParsingInformation) {
166
	public ConstructorDeclaration parseStatements(char[] source, int offset, int length, Map settings, boolean recordParsingInformation, boolean enabledStatementRecovery) {
166
		if (source == null) {
167
		if (source == null) {
167
			throw new IllegalArgumentException();
168
			throw new IllegalArgumentException();
168
		}
169
		}
Lines 172-177 Link Here
172
					compilerOptions, 
173
					compilerOptions, 
173
					new DefaultProblemFactory(Locale.getDefault()));
174
					new DefaultProblemFactory(Locale.getDefault()));
174
		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
175
		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
176
		parser.setStatementsRecovery(enabledStatementRecovery);
175
		
177
		
176
		ICompilationUnit sourceUnit = 
178
		ICompilationUnit sourceUnit = 
177
			new CompilationUnit(
179
			new CompilationUnit(
(-)model/org/eclipse/jdt/core/JavaCore.java (+7 lines)
Lines 657-662 Link Here
657
	/**
657
	/**
658
	 * Possible  configurable option ID.
658
	 * Possible  configurable option ID.
659
	 * @see #getDefaultOptions()
659
	 * @see #getDefaultOptions()
660
	 * @since 3.2
661
	 */
662
	//TODO It is a temporary option. It will removed before 3.2 release
663
	public static final String COMPILER_STATEMENTS_RECOVERY = PLUGIN_ID + ".compiler.statementsRecovery"; //$NON-NLS-1$
664
	/**
665
	 * Possible  configurable option ID.
666
	 * @see #getDefaultOptions()
660
	 */
667
	 */
661
	public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$
668
	public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$
662
	/**
669
	/**
(-)model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java (+1 lines)
Lines 415-420 Link Here
415
415
416
	// enable the compiler reference info support
416
	// enable the compiler reference info support
417
	options.produceReferenceInfo = true;
417
	options.produceReferenceInfo = true;
418
	options.performStatementsRecovery = false;
418
	
419
	
419
	org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment env = newCompiler.lookupEnvironment;
420
	org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment env = newCompiler.lookupEnvironment;
420
	synchronized (env) {
421
	synchronized (env) {
(-)formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java (-2 / +2 lines)
Lines 267-273 Link Here
267
			return this.newCodeFormatter2.format(source, (Block) node);
267
			return this.newCodeFormatter2.format(source, (Block) node);
268
		}
268
		}
269
		
269
		
270
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true);
270
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
271
		
271
		
272
		if (constructorDeclaration.statements == null) {
272
		if (constructorDeclaration.statements == null) {
273
			// a problem occured while parsing the source
273
			// a problem occured while parsing the source
Lines 469-475 Link Here
469
		}
469
		}
470
470
471
		// probe for statements
471
		// probe for statements
472
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true);
472
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
473
		if (constructorDeclaration.statements != null) {
473
		if (constructorDeclaration.statements != null) {
474
			if (USE_NEW_FORMATTER) {
474
			if (USE_NEW_FORMATTER) {
475
				ASTParser parser = ASTParser.newParser(AST.JLS3);
475
				ASTParser parser = ASTParser.newParser(AST.JLS3);
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java (-1 / +1 lines)
Lines 329-335 Link Here
329
		scope = new BlockScope(upperScope);
329
		scope = new BlockScope(upperScope);
330
		this.elementVariable.resolve(scope); // collection expression can see itemVariable
330
		this.elementVariable.resolve(scope); // collection expression can see itemVariable
331
		TypeBinding elementType = this.elementVariable.type.resolvedType;
331
		TypeBinding elementType = this.elementVariable.type.resolvedType;
332
		TypeBinding collectionType = this.collection.resolveType(scope);
332
		TypeBinding collectionType = this.collection == null ? null : this.collection.resolveType(scope);
333
		boolean hasError = elementType == null || collectionType == null;
333
		boolean hasError = elementType == null || collectionType == null;
334
334
335
		if (!hasError) {
335
		if (!hasError) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java (+2 lines)
Lines 178-183 Link Here
178
	
178
	
179
	public Constant constant;
179
	public Constant constant;
180
	
180
	
181
	public int statementEnd = -1;
182
	
181
	//Some expression may not be used - from a java semantic point
183
	//Some expression may not be used - from a java semantic point
182
	//of view only - as statements. Other may. In order to avoid the creation
184
	//of view only - as statements. Other may. In order to avoid the creation
183
	//of wrappers around expression in order to tune them as expression
185
	//of wrappers around expression in order to tune them as expression
(-)compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java (+3 lines)
Lines 130-135 Link Here
130
				localType.enclosingCase = null;
130
				localType.enclosingCase = null;
131
			}
131
			}
132
		}
132
		}
133
		
134
		compilationResult.recoveryScannerData = null; // recovery is already done
135
		
133
		ClassFile[] classFiles = compilationResult.getClassFiles();
136
		ClassFile[] classFiles = compilationResult.getClassFiles();
134
		for (int i = 0, max = classFiles.length; i < max; i++) {
137
		for (int i = 0, max = classFiles.length; i < max; i++) {
135
			// clear the classFile back pointer to the bindings
138
			// clear the classFile back pointer to the bindings
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (+30 lines)
Lines 2628-2633 Link Here
2628
public void invalidEnclosingType(Expression expression, TypeBinding type, ReferenceBinding enclosingType) {
2628
public void invalidEnclosingType(Expression expression, TypeBinding type, ReferenceBinding enclosingType) {
2629
2629
2630
	if (enclosingType.isAnonymousType()) enclosingType = enclosingType.superclass();
2630
	if (enclosingType.isAnonymousType()) enclosingType = enclosingType.superclass();
2631
	if (enclosingType.sourceName.length == 0) return;
2632
	
2631
	int flag = IProblem.UndefinedType; // default
2633
	int flag = IProblem.UndefinedType; // default
2632
	switch (type.problemId()) {
2634
	switch (type.problemId()) {
2633
		case ProblemReasons.NotFound : // 1
2635
		case ProblemReasons.NotFound : // 1
Lines 2675-2680 Link Here
2675
		expression.sourceEnd);
2677
		expression.sourceEnd);
2676
}
2678
}
2677
public void invalidField(FieldReference fieldRef, TypeBinding searchedType) {
2679
public void invalidField(FieldReference fieldRef, TypeBinding searchedType) {
2680
	if(fieldRef.token.length == 0) return;
2681
	
2678
	int id = IProblem.UndefinedField;
2682
	int id = IProblem.UndefinedField;
2679
	FieldBinding field = fieldRef.binding;
2683
	FieldBinding field = fieldRef.binding;
2680
	final int sourceStart= (int) (fieldRef.nameSourcePosition >> 32);
2684
	final int sourceStart= (int) (fieldRef.nameSourcePosition >> 32);
Lines 2730-2735 Link Here
2730
		fieldRef.sourceEnd);
2734
		fieldRef.sourceEnd);
2731
}
2735
}
2732
public void invalidField(NameReference nameRef, FieldBinding field) {
2736
public void invalidField(NameReference nameRef, FieldBinding field) {
2737
	if (nameRef instanceof QualifiedNameReference) {
2738
		QualifiedNameReference ref = (QualifiedNameReference) nameRef;
2739
		char[] lastToken = ref.tokens[ref.tokens.length - 1];
2740
		if (lastToken.length == 0) return;
2741
	} else {
2742
		SingleNameReference ref = (SingleNameReference) nameRef;
2743
		if (ref.token.length == 0) return;
2744
	}
2733
	int id = IProblem.UndefinedField;
2745
	int id = IProblem.UndefinedField;
2734
	switch (field.problemId()) {
2746
	switch (field.problemId()) {
2735
		case ProblemReasons.NotFound :
2747
		case ProblemReasons.NotFound :
Lines 2786-2791 Link Here
2786
	//UndefinedField
2798
	//UndefinedField
2787
	//NotVisibleField
2799
	//NotVisibleField
2788
	//AmbiguousField
2800
	//AmbiguousField
2801
	
2802
	char[] lastToken = nameRef.tokens[nameRef.tokens.length - 1];
2803
	if (lastToken.length == 0) return;
2789
2804
2790
	if (searchedType.isBaseType()) {
2805
	if (searchedType.isBaseType()) {
2791
		this.handle(
2806
		this.handle(
Lines 2863-2868 Link Here
2863
			annotation.sourceEnd);	
2878
			annotation.sourceEnd);	
2864
}
2879
}
2865
public void invalidMethod(MessageSend messageSend, MethodBinding method) {
2880
public void invalidMethod(MessageSend messageSend, MethodBinding method) {
2881
	if(messageSend.selector.length == 0) return;
2882
	
2866
	int id = IProblem.UndefinedMethod; //default...
2883
	int id = IProblem.UndefinedMethod; //default...
2867
    MethodBinding shownMethod = method;
2884
    MethodBinding shownMethod = method;
2868
	switch (method.problemId()) {
2885
	switch (method.problemId()) {
Lines 3148-3173 Link Here
3148
	int end = location.sourceEnd;
3165
	int end = location.sourceEnd;
3149
	if (location instanceof QualifiedNameReference) {
3166
	if (location instanceof QualifiedNameReference) {
3150
		QualifiedNameReference ref = (QualifiedNameReference) location;
3167
		QualifiedNameReference ref = (QualifiedNameReference) location;
3168
		if(ref.tokens[ref.tokens.length - 1].length == 0) return;
3151
		if (ref.indexOfFirstFieldBinding >= 1)
3169
		if (ref.indexOfFirstFieldBinding >= 1)
3152
			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
3170
			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
3153
	} else if (location instanceof ArrayQualifiedTypeReference) {
3171
	} else if (location instanceof ArrayQualifiedTypeReference) {
3154
		ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) location;
3172
		ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) location;
3173
		if(arrayQualifiedTypeReference.tokens[arrayQualifiedTypeReference.tokens.length - 1].length == 0) return;
3155
		long[] positions = arrayQualifiedTypeReference.sourcePositions;
3174
		long[] positions = arrayQualifiedTypeReference.sourcePositions;
3156
		end = (int) positions[positions.length - 1];
3175
		end = (int) positions[positions.length - 1];
3157
	} else if (location instanceof QualifiedTypeReference) {
3176
	} else if (location instanceof QualifiedTypeReference) {
3158
		QualifiedTypeReference ref = (QualifiedTypeReference) location;
3177
		QualifiedTypeReference ref = (QualifiedTypeReference) location;
3178
		if(ref.tokens[ref.tokens.length - 1].length == 0) return;
3159
		if (type instanceof ReferenceBinding) {
3179
		if (type instanceof ReferenceBinding) {
3160
			char[][] name = ((ReferenceBinding) type).compoundName;
3180
			char[][] name = ((ReferenceBinding) type).compoundName;
3161
			end = (int) ref.sourcePositions[name.length - 1];
3181
			end = (int) ref.sourcePositions[name.length - 1];
3162
		}
3182
		}
3163
	} else if (location instanceof ImportReference) {
3183
	} else if (location instanceof ImportReference) {
3164
		ImportReference ref = (ImportReference) location;
3184
		ImportReference ref = (ImportReference) location;
3185
		if (ref.tokens[ref.tokens.length - 1].length == 0) return;
3165
		if (type instanceof ReferenceBinding) {
3186
		if (type instanceof ReferenceBinding) {
3166
			char[][] name = ((ReferenceBinding) type).compoundName;
3187
			char[][] name = ((ReferenceBinding) type).compoundName;
3167
			end = (int) ref.sourcePositions[name.length - 1];
3188
			end = (int) ref.sourcePositions[name.length - 1];
3168
		}
3189
		}
3169
	} else if (location instanceof ArrayTypeReference) {
3190
	} else if (location instanceof ArrayTypeReference) {
3170
		ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location;
3191
		ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location;
3192
		if (arrayTypeReference.token.length == 0) return;
3171
		end = arrayTypeReference.originalSourceEnd;
3193
		end = arrayTypeReference.originalSourceEnd;
3172
	}
3194
	}
3173
	this.handle(
3195
	this.handle(
Lines 5274-5279 Link Here
5274
}
5296
}
5275
public void undefinedAnnotationValue(TypeBinding annotationType, MemberValuePair memberValuePair) {
5297
public void undefinedAnnotationValue(TypeBinding annotationType, MemberValuePair memberValuePair) {
5276
	String name = 	new String(memberValuePair.name);
5298
	String name = 	new String(memberValuePair.name);
5299
	if(name.length() == 0) return;
5277
	this.handle(
5300
	this.handle(
5278
		IProblem.UndefinedAnnotationMember,
5301
		IProblem.UndefinedAnnotationMember,
5279
		new String[] { name, new String(annotationType.readableName())},
5302
		new String[] { name, new String(annotationType.readableName())},
Lines 5283-5288 Link Here
5283
}
5306
}
5284
public void undefinedLabel(BranchStatement statement) {
5307
public void undefinedLabel(BranchStatement statement) {
5285
	String[] arguments = new String[] {new String(statement.label)};
5308
	String[] arguments = new String[] {new String(statement.label)};
5309
	if (statement.label.length == 0) return;
5286
	this.handle(
5310
	this.handle(
5287
		IProblem.UndefinedLabel,
5311
		IProblem.UndefinedLabel,
5288
		arguments,
5312
		arguments,
Lines 5292-5297 Link Here
5292
}
5316
}
5293
// can only occur inside binaries
5317
// can only occur inside binaries
5294
public void undefinedTypeVariableSignature(char[] variableName, ReferenceBinding binaryType) {
5318
public void undefinedTypeVariableSignature(char[] variableName, ReferenceBinding binaryType) {
5319
	if(variableName.length == 0)
5295
	this.handle(
5320
	this.handle(
5296
		IProblem.UndefinedTypeVariable,
5321
		IProblem.UndefinedTypeVariable,
5297
		new String[] {new String(variableName), new String(binaryType.readableName()) },	
5322
		new String[] {new String(variableName), new String(binaryType.readableName()) },	
Lines 5466-5473 Link Here
5466
	int end = nameRef.sourceEnd;
5491
	int end = nameRef.sourceEnd;
5467
	if (nameRef instanceof QualifiedNameReference) {
5492
	if (nameRef instanceof QualifiedNameReference) {
5468
		QualifiedNameReference ref = (QualifiedNameReference) nameRef;
5493
		QualifiedNameReference ref = (QualifiedNameReference) nameRef;
5494
		char[] lastToken = ref.tokens[ref.tokens.length - 1];
5495
		if (lastToken.length == 0) return;
5469
		if (ref.indexOfFirstFieldBinding >= 1)
5496
		if (ref.indexOfFirstFieldBinding >= 1)
5470
			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
5497
			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
5498
	} else {
5499
		SingleNameReference ref = (SingleNameReference) nameRef;
5500
		if (ref.token.length == 0) return;
5471
	}
5501
	}
5472
	this.handle(
5502
	this.handle(
5473
		IProblem.UndefinedName,
5503
		IProblem.UndefinedName,
(-)codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java (+2 lines)
Lines 75-80 Link Here
75
public AssistParser(ProblemReporter problemReporter) {
75
public AssistParser(ProblemReporter problemReporter) {
76
	super(problemReporter, true);
76
	super(problemReporter, true);
77
	this.javadocParser.checkDocComment = false;
77
	this.javadocParser.checkDocComment = false;
78
	
79
	this.setStatementsRecovery(false);
78
}
80
}
79
public abstract char[] assistIdentifier();
81
public abstract char[] assistIdentifier();
80
public int bodyEnd(AbstractMethodDeclaration method){
82
public int bodyEnd(AbstractMethodDeclaration method){
(-)batch/org/eclipse/jdt/internal/compiler/batch/Main.java (+1 lines)
Lines 2795-2800 Link Here
2795
		// set the non-externally configurable options.
2795
		// set the non-externally configurable options.
2796
		this.compilerOptions.verbose = this.verbose;
2796
		this.compilerOptions.verbose = this.verbose;
2797
		this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
2797
		this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
2798
		this.compilerOptions.performStatementsRecovery = false;
2798
		try {
2799
		try {
2799
			this.logger.startLoggingSources();
2800
			this.logger.startLoggingSources();
2800
			batchCompiler.compile(getCompilationUnits());
2801
			batchCompiler.compile(getCompilationUnits());
(-)compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java (-216 / +445 lines)
Lines 14-19 Link Here
14
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
14
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
15
import org.eclipse.jdt.internal.compiler.parser.Parser;
15
import org.eclipse.jdt.internal.compiler.parser.Parser;
16
import org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation;
16
import org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation;
17
import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
17
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
18
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
18
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
19
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
19
20
Lines 79-84 Link Here
79
	
80
	
80
	private Parser parser;
81
	private Parser parser;
81
	
82
	
83
	private RecoveryScanner recoveryScanner;
84
	
85
	private boolean reportProblem;
86
	
82
	private class RepairCandidate {
87
	private class RepairCandidate {
83
		public int symbol;
88
		public int symbol;
84
		public int location;
89
		public int location;
Lines 145-150 Link Here
145
		this.parser = parser;
150
		this.parser = parser;
146
		this.options = options;
151
		this.options = options;
147
		this.lexStream = new LexStream(BUFF_SIZE, parser.scanner, intervalStartToSkip, intervalEndToSkip, intervalFlagsToSkip, firstToken, start, end);
152
		this.lexStream = new LexStream(BUFF_SIZE, parser.scanner, intervalStartToSkip, intervalEndToSkip, intervalFlagsToSkip, firstToken, start, end);
153
		this.recoveryScanner = parser.recoveryScanner;
148
	}
154
	}
149
	
155
	
150
	private ProblemReporter problemReporter(){
156
	private ProblemReporter problemReporter(){
Lines 179-408 Link Here
179
	}
185
	}
180
186
181
187
182
	public void diagnoseParse() {
188
	public void diagnoseParse(boolean record) {
183
		lexStream.reset();
189
		this.reportProblem = true;
184
190
		boolean oldRecord = false;
185
		currentToken = lexStream.getToken();
191
		if(this.recoveryScanner != null) {
186
192
			oldRecord = this.recoveryScanner.record;
187
		int prev_pos;
193
			this.recoveryScanner.record = record;
188
		int pos;
194
		}
189
		int next_pos;
195
		try {
190
		int act = START_STATE;
196
			lexStream.reset();
191
197
	
192
		reallocateStacks();
198
			currentToken = lexStream.getToken();
193
199
	
194
		//
200
			int prev_pos;
195
		// Start parsing
201
			int pos;
196
		//
202
			int next_pos;
197
		stateStackTop = 0;
203
			int act = START_STATE;
198
		stack[stateStackTop] = act;
204
	
199
205
			reallocateStacks();
200
		int tok = lexStream.kind(currentToken);
206
	
201
		locationStack[stateStackTop] = currentToken;
202
		locationStartStack[stateStackTop] = lexStream.start(currentToken);
203
		
204
		boolean forceRecoveryAfterLBracketMissing = false;
205
//		int forceRecoveryToken = -1;
206
207
		//
208
		// Process a terminal
209
		//
210
		do {
211
			//
207
			//
212
			// Synchronize state stacks and update the location stack
208
			// Start parsing
213
			//
209
			//
214
			prev_pos = -1;
210
			stateStackTop = 0;
215
			prevStackTop = -1;
211
			stack[stateStackTop] = act;
216
212
	
217
			next_pos = -1;
213
			int tok = lexStream.kind(currentToken);
218
			nextStackTop = -1;
214
			locationStack[stateStackTop] = currentToken;
219
215
			locationStartStack[stateStackTop] = lexStream.start(currentToken);
220
			pos = stateStackTop;
216
			
221
			tempStackTop = stateStackTop - 1;
217
			boolean forceRecoveryAfterLBracketMissing = false;
222
			for (int i = 0; i <= stateStackTop; i++)
218
	//		int forceRecoveryToken = -1;
223
				tempStack[i] = stack[i];
219
	
224
225
			act = Parser.tAction(act, tok);
226
			//
220
			//
227
			// When a reduce action is encountered, we compute all REDUCE
221
			// Process a terminal
228
			// and associated goto actions induced by the current token.
229
			// Eventually, a SHIFT, SHIFT-REDUCE, ACCEPT or ERROR action is
230
			// computed...
231
			//
222
			//
232
			while (act <= NUM_RULES) {
223
			do {
233
				do {
234
					tempStackTop -= (Parser.rhs[act]-1);
235
					act = Parser.ntAction(tempStack[tempStackTop], Parser.lhs[act]);
236
				} while(act <= NUM_RULES);
237
				//
224
				//
238
				// ... Update the maximum useful position of the
225
				// Synchronize state stacks and update the location stack
239
				// (STATE_)STACK, push goto state into stack, and
240
				// compute next action on current symbol ...
241
				//
226
				//
242
				if (tempStackTop + 1 >= stackLength)
227
				prev_pos = -1;
243
					reallocateStacks();
228
				prevStackTop = -1;
244
				pos = pos < tempStackTop ? pos : tempStackTop;
229
	
245
				tempStack[tempStackTop + 1] = act;
230
				next_pos = -1;
231
				nextStackTop = -1;
232
	
233
				pos = stateStackTop;
234
				tempStackTop = stateStackTop - 1;
235
				for (int i = 0; i <= stateStackTop; i++)
236
					tempStack[i] = stack[i];
237
	
246
				act = Parser.tAction(act, tok);
238
				act = Parser.tAction(act, tok);
247
			}
248
249
			//
250
			// At this point, we have a shift, shift-reduce, accept or error
251
			// action.  STACK contains the configuration of the state stack
252
			// prior to executing any action on curtok. next_stack contains
253
			// the configuration of the state stack after executing all
254
			// reduce actions induced by curtok.  The variable pos indicates
255
			// the highest position in STACK that is still useful after the
256
			// reductions are executed.
257
			//
258
			while(act > ERROR_ACTION || act < ACCEPT_ACTION) { // SHIFT-REDUCE action or SHIFT action ?
259
				nextStackTop = tempStackTop + 1;
260
				for (int i = next_pos + 1; i <= nextStackTop; i++)
261
					nextStack[i] = tempStack[i];
262
263
				for (int i = pos + 1; i <= nextStackTop; i++) {
264
					locationStack[i] = locationStack[stateStackTop];
265
					locationStartStack[i] = locationStartStack[stateStackTop];
266
				}
267
268
				//
239
				//
269
				// If we have a shift-reduce, process it as well as
240
				// When a reduce action is encountered, we compute all REDUCE
270
				// the goto-reduce actions that follow it.
241
				// and associated goto actions induced by the current token.
242
				// Eventually, a SHIFT, SHIFT-REDUCE, ACCEPT or ERROR action is
243
				// computed...
271
				//
244
				//
272
				if (act > ERROR_ACTION) {
245
				while (act <= NUM_RULES) {
273
					act -= ERROR_ACTION;
274
					do {
246
					do {
275
						nextStackTop -= (Parser.rhs[act]-1);
276
						act = Parser.ntAction(nextStack[nextStackTop], Parser.lhs[act]);
277
					} while(act <= NUM_RULES);
278
					pos = pos < nextStackTop ? pos : nextStackTop;
279
				}
280
281
				if (nextStackTop + 1 >= stackLength)
282
					reallocateStacks();
283
284
				tempStackTop = nextStackTop;
285
				nextStack[++nextStackTop] = act;
286
				next_pos = nextStackTop;
287
288
				//
289
				// Simulate the parser through the next token without
290
				// destroying STACK or next_stack.
291
				//
292
				currentToken = lexStream.getToken();
293
				tok = lexStream.kind(currentToken);
294
				act = Parser.tAction(act, tok);
295
				while(act <= NUM_RULES) {
296
					//
297
					// ... Process all goto-reduce actions following
298
					// reduction, until a goto action is computed ...
299
					//
300
					do {
301
						int lhs_symbol = Parser.lhs[act];
302
						if(DEBUG) {
303
							System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
304
						}
305
						tempStackTop -= (Parser.rhs[act]-1);
247
						tempStackTop -= (Parser.rhs[act]-1);
306
						act = (tempStackTop > next_pos
248
						act = Parser.ntAction(tempStack[tempStackTop], Parser.lhs[act]);
307
								   ? tempStack[tempStackTop]
249
					} while(act <= NUM_RULES);
308
								   : nextStack[tempStackTop]);
309
						act = Parser.ntAction(act, lhs_symbol);
310
					}   while(act <= NUM_RULES);
311
312
					//
250
					//
313
					// ... Update the maximum useful position of the
251
					// ... Update the maximum useful position of the
314
					// (STATE_)STACK, push GOTO state into stack, and
252
					// (STATE_)STACK, push goto state into stack, and
315
					// compute next action on current symbol ...
253
					// compute next action on current symbol ...
316
					//
254
					//
317
					if (tempStackTop + 1 >= stackLength)
255
					if (tempStackTop + 1 >= stackLength)
318
						reallocateStacks();
256
						reallocateStacks();
319
257
					pos = pos < tempStackTop ? pos : tempStackTop;
320
					next_pos = next_pos < tempStackTop ? next_pos : tempStackTop;
321
					tempStack[tempStackTop + 1] = act;
258
					tempStack[tempStackTop + 1] = act;
322
					act = Parser.tAction(act, tok);
259
					act = Parser.tAction(act, tok);
323
				}
260
				}
324
261
	
325
//				if((tok != TokenNameRBRACE || (forceRecoveryToken != currentToken && (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0))
326
//					&& (lexStream.flags(currentToken) & LexStream.IS_AFTER_JUMP) !=0) {
327
//					act = ERROR_ACTION;
328
//					if(forceRecoveryToken != currentToken
329
//						&& (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0) {
330
//						forceRecoveryAfterLBracketMissing = true;
331
//						forceRecoveryToken = currentToken;
332
//					}
333
//				}
334
				
335
				//
336
				// No error was detected, Read next token into
337
				// PREVTOK element, advance CURTOK pointer and
338
				// update stacks.
339
				//
340
				if (act != ERROR_ACTION) {
341
					prevStackTop = stateStackTop;
342
					for (int i = prev_pos + 1; i <= prevStackTop; i++)
343
						prevStack[i] = stack[i];
344
					prev_pos = pos;
345
346
					stateStackTop = nextStackTop;
347
					for (int i = pos + 1; i <= stateStackTop; i++)
348
						stack[i] = nextStack[i];
349
					locationStack[stateStackTop] = currentToken;
350
					locationStartStack[stateStackTop] = lexStream.start(currentToken);
351
					pos = next_pos;
352
				}
353
			}
354
355
			//
356
			// At this stage, either we have an ACCEPT or an ERROR
357
			// action.
358
			//
359
			if (act == ERROR_ACTION) {
360
				//
262
				//
361
				// An error was detected.
263
				// At this point, we have a shift, shift-reduce, accept or error
264
				// action.  STACK contains the configuration of the state stack
265
				// prior to executing any action on curtok. next_stack contains
266
				// the configuration of the state stack after executing all
267
				// reduce actions induced by curtok.  The variable pos indicates
268
				// the highest position in STACK that is still useful after the
269
				// reductions are executed.
362
				//
270
				//
363
				RepairCandidate candidate = errorRecovery(currentToken, forceRecoveryAfterLBracketMissing);
271
				while(act > ERROR_ACTION || act < ACCEPT_ACTION) { // SHIFT-REDUCE action or SHIFT action ?
364
				
272
					nextStackTop = tempStackTop + 1;
365
				forceRecoveryAfterLBracketMissing = false;
273
					for (int i = next_pos + 1; i <= nextStackTop; i++)
366
				
274
						nextStack[i] = tempStack[i];
367
				if(parser.reportOnlyOneSyntaxError) {
275
	
368
					return;
276
					for (int i = pos + 1; i <= nextStackTop; i++) {
369
				}
277
						locationStack[i] = locationStack[stateStackTop];
370
				
278
						locationStartStack[i] = locationStartStack[stateStackTop];
371
				if(this.parser.problemReporter().options.maxProblemsPerUnit < this.parser.compilationUnit.compilationResult.problemCount) {
279
					}
372
					return;
280
	
281
					//
282
					// If we have a shift-reduce, process it as well as
283
					// the goto-reduce actions that follow it.
284
					//
285
					if (act > ERROR_ACTION) {
286
						act -= ERROR_ACTION;
287
						do {
288
							nextStackTop -= (Parser.rhs[act]-1);
289
							act = Parser.ntAction(nextStack[nextStackTop], Parser.lhs[act]);
290
						} while(act <= NUM_RULES);
291
						pos = pos < nextStackTop ? pos : nextStackTop;
292
					}
293
	
294
					if (nextStackTop + 1 >= stackLength)
295
						reallocateStacks();
296
	
297
					tempStackTop = nextStackTop;
298
					nextStack[++nextStackTop] = act;
299
					next_pos = nextStackTop;
300
	
301
					//
302
					// Simulate the parser through the next token without
303
					// destroying STACK or next_stack.
304
					//
305
					currentToken = lexStream.getToken();
306
					tok = lexStream.kind(currentToken);
307
					act = Parser.tAction(act, tok);
308
					while(act <= NUM_RULES) {
309
						//
310
						// ... Process all goto-reduce actions following
311
						// reduction, until a goto action is computed ...
312
						//
313
						do {
314
							int lhs_symbol = Parser.lhs[act];
315
							if(DEBUG) {
316
								System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
317
							}
318
							tempStackTop -= (Parser.rhs[act]-1);
319
							act = (tempStackTop > next_pos
320
									   ? tempStack[tempStackTop]
321
									   : nextStack[tempStackTop]);
322
							act = Parser.ntAction(act, lhs_symbol);
323
						}   while(act <= NUM_RULES);
324
	
325
						//
326
						// ... Update the maximum useful position of the
327
						// (STATE_)STACK, push GOTO state into stack, and
328
						// compute next action on current symbol ...
329
						//
330
						if (tempStackTop + 1 >= stackLength)
331
							reallocateStacks();
332
	
333
						next_pos = next_pos < tempStackTop ? next_pos : tempStackTop;
334
						tempStack[tempStackTop + 1] = act;
335
						act = Parser.tAction(act, tok);
336
					}
337
	
338
	//				if((tok != TokenNameRBRACE || (forceRecoveryToken != currentToken && (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0))
339
	//					&& (lexStream.flags(currentToken) & LexStream.IS_AFTER_JUMP) !=0) {
340
	//					act = ERROR_ACTION;
341
	//					if(forceRecoveryToken != currentToken
342
	//						&& (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0) {
343
	//						forceRecoveryAfterLBracketMissing = true;
344
	//						forceRecoveryToken = currentToken;
345
	//					}
346
	//				}
347
					
348
					//
349
					// No error was detected, Read next token into
350
					// PREVTOK element, advance CURTOK pointer and
351
					// update stacks.
352
					//
353
					if (act != ERROR_ACTION) {
354
						prevStackTop = stateStackTop;
355
						for (int i = prev_pos + 1; i <= prevStackTop; i++)
356
							prevStack[i] = stack[i];
357
						prev_pos = pos;
358
	
359
						stateStackTop = nextStackTop;
360
						for (int i = pos + 1; i <= stateStackTop; i++)
361
							stack[i] = nextStack[i];
362
						locationStack[stateStackTop] = currentToken;
363
						locationStartStack[stateStackTop] = lexStream.start(currentToken);
364
						pos = next_pos;
365
					}
373
				}
366
				}
374
367
	
375
				act = stack[stateStackTop];
376
377
				//
368
				//
378
				// If the recovery was successful on a nonterminal candidate,
369
				// At this stage, either we have an ACCEPT or an ERROR
379
				// parse through that candidate and "read" the next token.
370
				// action.
380
				//
371
				//
381
				if (candidate.symbol == 0) {
372
				if (act == ERROR_ACTION) {
382
					break;
373
					//
383
				} else if (candidate.symbol > NT_OFFSET) {
374
					// An error was detected.
384
					int lhs_symbol = candidate.symbol - NT_OFFSET;
375
					//
385
					if(DEBUG) {
376
					RepairCandidate candidate = errorRecovery(currentToken, forceRecoveryAfterLBracketMissing);
386
						System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
377
					
378
					forceRecoveryAfterLBracketMissing = false;
379
					
380
					if(parser.reportOnlyOneSyntaxError) {
381
						return;
387
					}
382
					}
388
					act = Parser.ntAction(act, lhs_symbol);
383
					
389
					while(act <= NUM_RULES) {
384
					if(this.parser.problemReporter().options.maxProblemsPerUnit < this.parser.compilationUnit.compilationResult.problemCount) {						
390
						stateStackTop -= (Parser.rhs[act]-1);
385
						if(this.recoveryScanner == null) return;
391
						act = Parser.ntAction(stack[stateStackTop], Parser.lhs[act]);
386
						this.reportProblem = false;
387
					}
388
	
389
					act = stack[stateStackTop];
390
	
391
					//
392
					// If the recovery was successful on a nonterminal candidate,
393
					// parse through that candidate and "read" the next token.
394
					//
395
					if (candidate.symbol == 0) {
396
						break;
397
					} else if (candidate.symbol > NT_OFFSET) {
398
						int lhs_symbol = candidate.symbol - NT_OFFSET;
399
						if(DEBUG) {
400
							System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
401
						}
402
						act = Parser.ntAction(act, lhs_symbol);
403
						while(act <= NUM_RULES) {
404
							stateStackTop -= (Parser.rhs[act]-1);
405
							act = Parser.ntAction(stack[stateStackTop], Parser.lhs[act]);
406
						}
407
						stack[++stateStackTop] = act;
408
						currentToken = lexStream.getToken();
409
						tok = lexStream.kind(currentToken);
410
						locationStack[stateStackTop] = currentToken;
411
						locationStartStack[stateStackTop] = lexStream.start(currentToken);
412
					} else {
413
						tok = candidate.symbol;
414
						locationStack[stateStackTop] = candidate.location;
415
						locationStartStack[stateStackTop] = lexStream.start(candidate.location);
392
					}
416
					}
393
					stack[++stateStackTop] = act;
394
					currentToken = lexStream.getToken();
395
					tok = lexStream.kind(currentToken);
396
					locationStack[stateStackTop] = currentToken;
397
					locationStartStack[stateStackTop] = lexStream.start(currentToken);
398
				} else {
399
					tok = candidate.symbol;
400
					locationStack[stateStackTop] = candidate.location;
401
					locationStartStack[stateStackTop] = lexStream.start(candidate.location);
402
				}
417
				}
418
			} while (act != ACCEPT_ACTION);
419
		} finally {
420
			if(this.recoveryScanner != null) {
421
				this.recoveryScanner.record = oldRecord;
403
			}
422
			}
404
		} while (act != ACCEPT_ACTION);
423
		}
405
406
		return;
424
		return;
407
	}
425
	}
408
426
Lines 2084-2092 Link Here
2084
		String errorTokenName = Parser.name[Parser.terminal_index[lexStream.kind(token)]];
2102
		String errorTokenName = Parser.name[Parser.terminal_index[lexStream.kind(token)]];
2085
		char[] errorTokenSource = lexStream.name(token);
2103
		char[] errorTokenSource = lexStream.name(token);
2086
2104
2105
		int addedToken = -1;
2106
		if(recoveryScanner != null) {
2107
			if (nameIndex >= 0) {
2108
				addedToken = Parser.reverse_index[nameIndex];
2109
			}
2110
		}
2087
		switch(msgCode) {
2111
		switch(msgCode) {
2088
			case BEFORE_CODE:
2112
			case BEFORE_CODE:
2089
				problemReporter().parseErrorInsertBeforeToken(
2113
				if(recoveryScanner != null) {
2114
					if(addedToken > -1) {
2115
						recoveryScanner.insertToken(addedToken, -1, errorStart);
2116
					} else {
2117
						int[] template = getNTermTemplate(-addedToken);
2118
						if(template != null) {
2119
							recoveryScanner.insertTokens(template, -1, errorStart);
2120
						}
2121
					}
2122
				}
2123
				if(this.reportProblem) problemReporter().parseErrorInsertBeforeToken(
2090
					errorStart, 
2124
					errorStart, 
2091
					errorEnd, 
2125
					errorEnd, 
2092
					currentKind,
2126
					currentKind,
Lines 2095-2101 Link Here
2095
					name);
2129
					name);
2096
				 break;
2130
				 break;
2097
			case INSERTION_CODE:
2131
			case INSERTION_CODE:
2098
				problemReporter().parseErrorInsertAfterToken(
2132
				if(recoveryScanner != null) {
2133
					if(addedToken > -1) {
2134
						recoveryScanner.insertToken(addedToken, -1, errorEnd);
2135
					} else {
2136
						int[] template = getNTermTemplate(-addedToken);
2137
						if(template != null) {
2138
							recoveryScanner.insertTokens(template, -1, errorEnd);
2139
						}
2140
					}
2141
				}
2142
				if(this.reportProblem) problemReporter().parseErrorInsertAfterToken(
2099
					errorStart, 
2143
					errorStart, 
2100
					errorEnd, 
2144
					errorEnd, 
2101
					currentKind,
2145
					currentKind,
Lines 2104-2110 Link Here
2104
					name);  
2148
					name);  
2105
				 break;
2149
				 break;
2106
			case DELETION_CODE:
2150
			case DELETION_CODE:
2107
				problemReporter().parseErrorDeleteToken(
2151
				if(recoveryScanner != null) {
2152
					recoveryScanner.removeTokens(errorStart, errorEnd);
2153
				}
2154
				if(this.reportProblem) problemReporter().parseErrorDeleteToken(
2108
					errorStart, 
2155
					errorStart, 
2109
					errorEnd, 
2156
					errorEnd, 
2110
					currentKind,
2157
					currentKind,
Lines 2113-2119 Link Here
2113
				break;
2160
				break;
2114
			case INVALID_CODE:
2161
			case INVALID_CODE:
2115
				if (name.length() == 0) {
2162
				if (name.length() == 0) {
2116
					problemReporter().parseErrorReplaceToken(
2163
					if(recoveryScanner != null) {
2164
						recoveryScanner.removeTokens(errorStart, errorEnd);
2165
					}
2166
					if(this.reportProblem) problemReporter().parseErrorReplaceToken(
2117
						errorStart, 
2167
						errorStart, 
2118
						errorEnd, 
2168
						errorEnd, 
2119
						currentKind,
2169
						currentKind,
Lines 2121-2127 Link Here
2121
						errorTokenName, 
2171
						errorTokenName, 
2122
						name);
2172
						name);
2123
				} else {
2173
				} else {
2124
					problemReporter().parseErrorInvalidToken(
2174
					if(recoveryScanner != null) {
2175
						if(addedToken > -1) {
2176
							recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
2177
						} else {
2178
							int[] template = getNTermTemplate(-addedToken);
2179
							if(template != null) {
2180
								recoveryScanner.replaceTokens(template, errorStart, errorEnd);
2181
							}
2182
						}
2183
					}
2184
					if(this.reportProblem) problemReporter().parseErrorInvalidToken(
2125
						errorStart, 
2185
						errorStart, 
2126
						errorEnd, 
2186
						errorEnd, 
2127
						currentKind,
2187
						currentKind,
Lines 2131-2137 Link Here
2131
				}
2191
				}
2132
				break;
2192
				break;
2133
			case SUBSTITUTION_CODE:
2193
			case SUBSTITUTION_CODE:
2134
				problemReporter().parseErrorReplaceToken(
2194
				if(recoveryScanner != null) {
2195
					if(addedToken > -1) {
2196
						recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
2197
					} else {
2198
						int[] template = getNTermTemplate(-addedToken);
2199
						if(template != null) {
2200
							recoveryScanner.replaceTokens(template, errorStart, errorEnd);
2201
						}
2202
					}
2203
				}
2204
				if(this.reportProblem) problemReporter().parseErrorReplaceToken(
2135
					errorStart, 
2205
					errorStart, 
2136
					errorEnd, 
2206
					errorEnd, 
2137
					currentKind,
2207
					currentKind,
Lines 2141-2161 Link Here
2141
				 break;
2211
				 break;
2142
			case SCOPE_CODE:
2212
			case SCOPE_CODE:
2143
				StringBuffer buf = new StringBuffer();
2213
				StringBuffer buf = new StringBuffer();
2214
				
2215
				int[] addedTokens = null;
2216
	            int addedTokenCount = 0;
2217
	            if(this.recoveryScanner != null) {
2218
	            	addedTokens = new int[Parser.scope_rhs.length - Parser.scope_suffix[- nameIndex]];
2219
	            }
2220
	            
2144
				for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
2221
				for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
2145
					buf.append(Parser.readableName[Parser.scope_rhs[i]]);
2222
					buf.append(Parser.readableName[Parser.scope_rhs[i]]);
2146
					if (Parser.scope_rhs[i + 1] != 0) // any more symbols to print?
2223
					if (Parser.scope_rhs[i + 1] != 0) // any more symbols to print?
2147
						buf.append(' ');
2224
						buf.append(' ');
2148
						
2225
					
2226
					if(addedTokens != null) {
2227
	                	int tmpAddedToken = Parser.reverse_index[Parser.scope_rhs[i]];
2228
		                if (tmpAddedToken > -1) {
2229
		                	int length = addedTokens.length;
2230
		                	if(addedTokenCount == length) {
2231
		                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
2232
		                	}
2233
		                	addedTokens[addedTokenCount++] = tmpAddedToken;
2234
		                } else {
2235
		                	int[] template = getNTermTemplate(-tmpAddedToken);
2236
		                	if(template != null) {
2237
			                	for (int j = 0; j < template.length; j++) {
2238
									int length = addedTokens.length;
2239
		                			if(addedTokenCount == length) {
2240
				                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
2241
				                	}
2242
		                			addedTokens[addedTokenCount++] = template[j];
2243
								}
2244
		                	} else {
2245
			                	addedTokenCount = 0;
2246
			                	addedTokens = null;
2247
		                	}
2248
		                }
2249
	                }
2149
				}
2250
				}
2150
2251
2252
				if(addedTokenCount > 0) {
2253
	            	System.arraycopy(addedTokens, 0, addedTokens = new int[addedTokenCount], 0, addedTokenCount);
2254
	            	
2255
	            	int completedToken = -1;
2256
	            	if(scopeNameIndex != 0) {
2257
	            		completedToken = -Parser.reverse_index[scopeNameIndex];
2258
	            	}
2259
	            	this.recoveryScanner.insertTokens(addedTokens, completedToken, errorEnd);
2260
	            }
2261
				
2151
				if (scopeNameIndex != 0) {
2262
				if (scopeNameIndex != 0) {
2152
					problemReporter().parseErrorInsertToComplete(
2263
					if(this.reportProblem) problemReporter().parseErrorInsertToComplete(
2153
						errorStart, 
2264
						errorStart, 
2154
						errorEnd,
2265
						errorEnd,
2155
						buf.toString(),
2266
						buf.toString(),
2156
						Parser.readableName[scopeNameIndex]);
2267
						Parser.readableName[scopeNameIndex]);
2157
				} else {
2268
				} else {
2158
					problemReporter().parseErrorInsertToCompleteScope(
2269
					if(this.reportProblem) problemReporter().parseErrorInsertToCompleteScope(
2159
						errorStart, 
2270
						errorStart, 
2160
						errorEnd,
2271
						errorEnd,
2161
						buf.toString()); 
2272
						buf.toString()); 
Lines 2163-2193 Link Here
2163
				
2274
				
2164
				break;
2275
				break;
2165
			case EOF_CODE:
2276
			case EOF_CODE:
2166
				problemReporter().parseErrorUnexpectedEnd(
2277
				if(this.reportProblem) problemReporter().parseErrorUnexpectedEnd(
2167
					errorStart, 
2278
					errorStart, 
2168
					errorEnd); 
2279
					errorEnd); 
2169
				break;
2280
				break;
2170
			case MERGE_CODE:
2281
			case MERGE_CODE:
2171
				problemReporter().parseErrorMergeTokens(
2282
				if(recoveryScanner != null) {
2283
					if(addedToken > -1) {
2284
						recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
2285
					} else {
2286
						int[] template = getNTermTemplate(-addedToken);
2287
						if(template != null) {
2288
							recoveryScanner.replaceTokens(template, errorStart, errorEnd);
2289
						}
2290
					}
2291
				}
2292
				if(this.reportProblem) problemReporter().parseErrorMergeTokens(
2172
					errorStart, 
2293
					errorStart, 
2173
					errorEnd,
2294
					errorEnd,
2174
					name);
2295
					name);
2175
				break;
2296
				break;
2176
			case MISPLACED_CODE:
2297
			case MISPLACED_CODE:
2177
				problemReporter().parseErrorMisplacedConstruct(
2298
				if(recoveryScanner != null) {
2299
					recoveryScanner.removeTokens(errorStart, errorEnd);
2300
				}
2301
				if(this.reportProblem) problemReporter().parseErrorMisplacedConstruct(
2178
					errorStart, 
2302
					errorStart, 
2179
					errorEnd);
2303
					errorEnd);
2180
				break;
2304
				break;
2181
			default:
2305
			default:
2182
				if (name.length() == 0) {
2306
				if (name.length() == 0) {
2183
					problemReporter().parseErrorNoSuggestion(
2307
					if(recoveryScanner != null) {
2308
						recoveryScanner.removeTokens(errorStart, errorEnd);
2309
					}
2310
					if(this.reportProblem) problemReporter().parseErrorNoSuggestion(
2184
						errorStart, 
2311
						errorStart, 
2185
						errorEnd, 
2312
						errorEnd, 
2186
						currentKind,
2313
						currentKind,
2187
						errorTokenSource, 
2314
						errorTokenSource, 
2188
						errorTokenName);
2315
						errorTokenName);
2189
				} else {
2316
				} else {
2190
					problemReporter().parseErrorReplaceToken(
2317
					if(recoveryScanner != null) {
2318
						if(addedToken > -1) {
2319
							recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
2320
						} else {
2321
							int[] template = getNTermTemplate(-addedToken);
2322
							if(template != null) {
2323
								recoveryScanner.replaceTokens(template, errorStart, errorEnd);
2324
							}
2325
						}
2326
					}
2327
					if(this.reportProblem) problemReporter().parseErrorReplaceToken(
2191
						errorStart, 
2328
						errorStart, 
2192
						errorEnd, 
2329
						errorEnd, 
2193
						currentKind,
2330
						currentKind,
Lines 2230-2238 Link Here
2230
		}
2367
		}
2231
		int errorEnd = lexStream.end(rightToken);
2368
		int errorEnd = lexStream.end(rightToken);
2232
		
2369
		
2370
		int addedToken = -1;
2371
		if(recoveryScanner != null) {
2372
			if (nameIndex >= 0) {
2373
				addedToken = Parser.reverse_index[nameIndex];
2374
			}
2375
		}
2376
		
2233
		switch(msgCode) {
2377
		switch(msgCode) {
2234
			case MISPLACED_CODE:
2378
			case MISPLACED_CODE:
2235
				problemReporter().parseErrorMisplacedConstruct(
2379
				if(recoveryScanner != null) {
2380
					recoveryScanner.removeTokens(errorStart, errorEnd);
2381
				}
2382
				if(this.reportProblem) problemReporter().parseErrorMisplacedConstruct(
2236
					errorStart, 
2383
					errorStart, 
2237
					errorEnd); 
2384
					errorEnd); 
2238
				break;
2385
				break;
Lines 2241-2282 Link Here
2241
				errorStart = lexStream.start(rightToken);
2388
				errorStart = lexStream.start(rightToken);
2242
			
2389
			
2243
	            StringBuffer buf = new StringBuffer();
2390
	            StringBuffer buf = new StringBuffer();
2391
	            
2392
	            int[] addedTokens = null;
2393
	            int addedTokenCount = 0;
2394
	            if(this.recoveryScanner != null) {
2395
	            	addedTokens = new int[Parser.scope_rhs.length - Parser.scope_suffix[- nameIndex]];
2396
	            }
2397
	            
2244
	            for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
2398
	            for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
2399
	                
2245
	                buf.append(Parser.readableName[Parser.scope_rhs[i]]);
2400
	                buf.append(Parser.readableName[Parser.scope_rhs[i]]);
2246
	                if (Parser.scope_rhs[i+1] != 0)
2401
	                if (Parser.scope_rhs[i+1] != 0)
2247
	                     buf.append(' ');
2402
	                     buf.append(' ');
2403
	                
2404
	                if(addedTokens != null) {
2405
	                	int tmpAddedToken = Parser.reverse_index[Parser.scope_rhs[i]];
2406
		                if (tmpAddedToken > -1) {
2407
		                	int length = addedTokens.length;
2408
		                	if(addedTokenCount == length) {
2409
		                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
2410
		                	}
2411
		                	addedTokens[addedTokenCount++] = tmpAddedToken;
2412
		                } else {
2413
		                	int[] template = getNTermTemplate(-tmpAddedToken);
2414
		                	if(template != null) {
2415
			                	for (int j = 0; j < template.length; j++) {
2416
									int length = addedTokens.length;
2417
		                			if(addedTokenCount == length) {
2418
				                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
2419
				                	}
2420
		                			addedTokens[addedTokenCount++] = template[j];
2421
								}
2422
		                	} else {
2423
			                	addedTokenCount = 0;
2424
			                	addedTokens = null;
2425
		                	}
2426
		                }
2427
	                }
2428
	            }
2429
	            if(addedTokenCount > 0) {
2430
	            	System.arraycopy(addedTokens, 0, addedTokens = new int[addedTokenCount], 0, addedTokenCount);
2431
	            	int completedToken = -1;
2432
	            	if(scopeNameIndex != 0) {
2433
	            		completedToken = -Parser.reverse_index[scopeNameIndex];
2434
	            	}
2435
	            	this.recoveryScanner.insertTokens(addedTokens, completedToken, errorEnd);
2248
	            }
2436
	            }
2249
	            if (scopeNameIndex != 0) {
2437
	            if (scopeNameIndex != 0) {
2250
	                problemReporter().parseErrorInsertToComplete(
2438
	                if(this.reportProblem) problemReporter().parseErrorInsertToComplete(
2251
						errorStart, 
2439
						errorStart, 
2252
						errorEnd,
2440
						errorEnd,
2253
						buf.toString(),
2441
						buf.toString(),
2254
						Parser.readableName[scopeNameIndex]);
2442
						Parser.readableName[scopeNameIndex]);
2255
	            } else {
2443
	            } else {
2256
	            	problemReporter().parseErrorInsertToCompletePhrase(
2444
	            	if(this.reportProblem) problemReporter().parseErrorInsertToCompletePhrase(
2257
						errorStart, 
2445
						errorStart, 
2258
						errorEnd,
2446
						errorEnd,
2259
						buf.toString()); 
2447
						buf.toString()); 
2260
	            }
2448
	            }
2261
	            break;
2449
	            break;
2262
			case MERGE_CODE:
2450
			case MERGE_CODE:
2263
				problemReporter().parseErrorMergeTokens(
2451
				if(recoveryScanner != null) {
2452
					if(addedToken > -1) {
2453
						recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
2454
					} else {
2455
						int[] template = getNTermTemplate(-addedToken);
2456
						if(template != null) {
2457
							recoveryScanner.replaceTokens(template, errorStart, errorEnd);
2458
						}
2459
					}
2460
				}
2461
				if(this.reportProblem) problemReporter().parseErrorMergeTokens(
2264
					errorStart, 
2462
					errorStart, 
2265
					errorEnd,
2463
					errorEnd,
2266
					name);
2464
					name);
2267
				break;
2465
				break;
2268
			case DELETION_CODE:
2466
			case DELETION_CODE:
2269
				problemReporter().parseErrorDeleteTokens(
2467
				if(recoveryScanner != null) {
2468
					recoveryScanner.removeTokens(errorStart, errorEnd);
2469
				}
2470
				if(this.reportProblem) problemReporter().parseErrorDeleteTokens(
2270
					errorStart, 
2471
					errorStart, 
2271
					errorEnd);
2472
					errorEnd);
2272
				break;
2473
				break;
2273
			default:
2474
			default:
2274
				if (name.length() == 0) {
2475
				if (name.length() == 0) {
2275
					problemReporter().parseErrorNoSuggestionForTokens(
2476
					if(recoveryScanner != null) {
2477
						recoveryScanner.removeTokens(errorStart, errorEnd);
2478
					}
2479
					if(this.reportProblem) problemReporter().parseErrorNoSuggestionForTokens(
2276
						errorStart, 
2480
						errorStart, 
2277
						errorEnd);
2481
						errorEnd);
2278
				} else {
2482
				} else {
2279
					problemReporter().parseErrorReplaceTokens(
2483
					if(recoveryScanner != null) {
2484
						if(addedToken > -1) {
2485
							recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
2486
						} else {
2487
							int[] template = getNTermTemplate(-addedToken);
2488
							if(template != null) {
2489
								recoveryScanner.replaceTokens(template, errorStart, errorEnd);
2490
							}
2491
						}
2492
					}
2493
					if(this.reportProblem) problemReporter().parseErrorReplaceTokens(
2280
						errorStart, 
2494
						errorStart, 
2281
						errorEnd,
2495
						errorEnd,
2282
						name);
2496
						name);
Lines 2285-2290 Link Here
2285
		return;
2499
		return;
2286
	}
2500
	}
2287
2501
2502
	private int[] getNTermTemplate(int sym) {
2503
		int templateIndex = Parser.recovery_templates_index[sym];
2504
    	if(templateIndex > 0) {
2505
    		int[] result = new int[Parser.recovery_templates.length];
2506
    		int count = 0;
2507
    		for(int j = templateIndex; Parser.recovery_templates[j] != 0; j++) {
2508
    			result[count++] = Parser.recovery_templates[j];
2509
    		}
2510
    		System.arraycopy(result, 0, result = new int[count], 0, count);
2511
    		return result;
2512
    	} else {
2513
        	return null;
2514
    	}
2515
	}
2516
	
2288
	public String toString() {
2517
	public String toString() {
2289
		StringBuffer res = new StringBuffer();
2518
		StringBuffer res = new StringBuffer();
2290
		
2519
		
(-)compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java (-2 / +15 lines)
Lines 113-118 Link Here
113
	/* should surface ??? */
113
	/* should surface ??? */
114
	public static final String OPTION_PrivateConstructorAccess = "org.eclipse.jdt.core.compiler.codegen.constructorAccessEmulation"; //$NON-NLS-1$
114
	public static final String OPTION_PrivateConstructorAccess = "org.eclipse.jdt.core.compiler.codegen.constructorAccessEmulation"; //$NON-NLS-1$
115
115
116
	//TODO temporary option
117
	public static final String OPTION_StatementsRecovery = "org.eclipse.jdt.core.compiler.statementsRecovery"; //$NON-NLS-1$
118
116
	/**
119
	/**
117
	 * Possible values for configurable options
120
	 * Possible values for configurable options
118
	 */
121
	 */
Lines 187-193 Link Here
187
	public static final long RawTypeReference = ASTNode.Bit46L;
190
	public static final long RawTypeReference = ASTNode.Bit46L;
188
	public static final long UnusedLabel = ASTNode.Bit47L;
191
	public static final long UnusedLabel = ASTNode.Bit47L;
189
	public static final long ParameterAssignment = ASTNode.Bit48L;
192
	public static final long ParameterAssignment = ASTNode.Bit48L;
190
193
	
191
	// Default severity level for handlers
194
	// Default severity level for handlers
192
	public long errorThreshold = 0;
195
	public long errorThreshold = 0;
193
		
196
		
Lines 296-304 Link Here
296
	// treat optional error as fatal or just like warning?
299
	// treat optional error as fatal or just like warning?
297
	public boolean treatOptionalErrorAsFatal = true;
300
	public boolean treatOptionalErrorAsFatal = true;
298
	
301
	
302
	// parser perform statements recovery 
303
	public boolean performStatementsRecovery = true;
304
	
299
	// store annotations
305
	// store annotations
300
	public boolean storeAnnotations = false;
306
	public boolean storeAnnotations = false;
301
307
	
302
	/** 
308
	/** 
303
	 * Initializing the compiler options with defaults
309
	 * Initializing the compiler options with defaults
304
	 */
310
	 */
Lines 726-731 Link Here
726
				this.reportMissingJavadocCommentsOverriding = false;
732
				this.reportMissingJavadocCommentsOverriding = false;
727
			}
733
			}
728
		}
734
		}
735
		if ((optionValue = optionsMap.get(OPTION_StatementsRecovery)) != null) {
736
			if (ENABLED.equals(optionValue)) {
737
				this.performStatementsRecovery = true;
738
			} else if (DISABLED.equals(optionValue)) {
739
				this.performStatementsRecovery = false;
740
			}
741
		}
729
	}
742
	}
730
743
731
	public String toString() {
744
	public String toString() {
(-)model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java (-1 / +2 lines)
Lines 43-49 Link Here
43
		defaultOptionsMap.put(JavaCore.COMPILER_TASK_CASE_SENSITIVE, JavaCore.ENABLED);
43
		defaultOptionsMap.put(JavaCore.COMPILER_TASK_CASE_SENSITIVE, JavaCore.ENABLED);
44
		defaultOptionsMap.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
44
		defaultOptionsMap.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
45
		defaultOptionsMap.put(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
45
		defaultOptionsMap.put(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
46
	
46
		defaultOptionsMap.put(JavaCore.COMPILER_STATEMENTS_RECOVERY, JavaCore.DISABLED); //TODO It is a temporary option
47
		
47
		// Builder settings
48
		// Builder settings
48
		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
49
		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
49
		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.ABORT); 
50
		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.ABORT); 
(-)compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java (+2 lines)
Lines 42-47 Link Here
42
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
42
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
43
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
43
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
44
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
44
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
45
import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
45
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
46
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
46
47
47
public class CompilationResult {
48
public class CompilationResult {
Lines 60-65 Link Here
60
	public boolean hasAnnotations = false;
61
	public boolean hasAnnotations = false;
61
62
62
	public int lineSeparatorPositions[];
63
	public int lineSeparatorPositions[];
64
	public RecoveryScannerData recoveryScannerData;
63
	public Map compiledTypes = new Hashtable(11);
65
	public Map compiledTypes = new Hashtable(11);
64
	public int unitIndex, totalUnitsKnown;
66
	public int unitIndex, totalUnitsKnown;
65
	public boolean hasBeenAccepted = false;
67
	public boolean hasBeenAccepted = false;
(-)compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScannerData.java (+65 lines)
Added Link Here
1
/**
2
 * 
3
 */
4
package org.eclipse.jdt.internal.compiler.parser;
5
6
public class RecoveryScannerData {
7
	public int insertedTokensPtr = -1;
8
	public int[][] insertedTokens;
9
	public int[] insertedTokensPosition;
10
	public boolean[] insertedTokenUsed;
11
	
12
	public int replacedTokensPtr = -1;
13
	public int[][] replacedTokens;
14
	public int[] replacedTokensStart;
15
	public int[] replacedTokensEnd;
16
	public boolean[] replacedTokenUsed;
17
		
18
	public int removedTokensPtr = -1;
19
	public int[] removedTokensStart;
20
	public int[] removedTokensEnd;
21
	public boolean[] removedTokenUsed;
22
	
23
	public RecoveryScannerData removeUnused() {
24
		if(this.insertedTokens != null) {
25
			int newInsertedTokensPtr = -1;
26
			for (int i = 0; i <= this.insertedTokensPtr; i++) {
27
				if(this.insertedTokenUsed[i]) {
28
					newInsertedTokensPtr++;
29
					this.insertedTokens[newInsertedTokensPtr] = this.insertedTokens[i];
30
					this.insertedTokensPosition[newInsertedTokensPtr] = this.insertedTokensPosition[i];
31
					this.insertedTokenUsed[newInsertedTokensPtr] = this.insertedTokenUsed[i];
32
				}
33
			}
34
			this.insertedTokensPtr = newInsertedTokensPtr;
35
		}
36
37
		if(this.replacedTokens != null) {
38
			int newReplacedTokensPtr = -1;
39
			for (int i = 0; i <= this.replacedTokensPtr; i++) {
40
				if(this.replacedTokenUsed[i]) {
41
					newReplacedTokensPtr++;
42
					this.replacedTokens[newReplacedTokensPtr] = this.replacedTokens[i];
43
					this.replacedTokensStart[newReplacedTokensPtr] = this.replacedTokensStart[i];
44
					this.replacedTokensEnd[newReplacedTokensPtr] = this.replacedTokensEnd[i];
45
					this.replacedTokenUsed[newReplacedTokensPtr] = this.replacedTokenUsed[i];
46
				}
47
			}
48
			this.replacedTokensPtr = newReplacedTokensPtr;
49
		}
50
		if(this.removedTokensStart != null) {
51
			int newRemovedTokensPtr = -1;
52
			for (int i = 0; i <= this.removedTokensPtr; i++) {
53
				if(this.removedTokenUsed[i]) {
54
					newRemovedTokensPtr++;
55
					this.removedTokensStart[newRemovedTokensPtr] = this.removedTokensStart[i];
56
					this.removedTokensEnd[newRemovedTokensPtr] = this.removedTokensEnd[i];
57
					this.removedTokenUsed[newRemovedTokensPtr] = this.removedTokenUsed[i];
58
				}
59
			}
60
			this.removedTokensPtr = newRemovedTokensPtr;
61
		}
62
		
63
		return this;
64
	}
65
}
(-)compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java (+186 lines)
Added Link Here
1
package org.eclipse.jdt.internal.compiler.parser;
2
3
import org.eclipse.jdt.core.compiler.CharOperation;
4
import org.eclipse.jdt.core.compiler.InvalidInputException;
5
6
public class RecoveryScanner extends Scanner {
7
	private RecoveryScannerData data;
8
	
9
	private int[] pendingTokens;
10
	private int pendingTokensPtr = -1;
11
	private char[] fakeTokenSource = null;
12
	private int skipNextInsertedTokens = -1;
13
14
	public boolean record = true;
15
	
16
	public RecoveryScanner(Scanner scanner, RecoveryScannerData data) {
17
		super(false,
18
				scanner.tokenizeWhiteSpace,
19
				scanner.checkNonExternalizedStringLiterals,
20
				scanner.sourceLevel,
21
				scanner.complianceLevel,
22
				scanner.taskTags,
23
				scanner.taskPriorities,
24
				scanner.isTaskCaseSensitive);
25
		this.setData(data);
26
	}
27
	
28
	public void insertToken(int token, int completedToken, int position) {
29
		insertTokens(new int []{token}, completedToken, position);
30
	}
31
	
32
	private int[] reverse(int[] tokens) {
33
		int length = tokens.length;
34
		for(int i = 0, max = length / 2; i < max; i++) {
35
			int tmp = tokens[i];
36
			tokens[i] = tokens[length - i - 1];
37
			tokens[length - i - 1] = tmp;
38
		}
39
		return tokens;
40
	}
41
	public void insertTokens(int[] tokens, int completedToken, int position) {
42
		if(!this.record) return;
43
		
44
		if(completedToken > -1 && Parser.statements_recovery_filter[completedToken] != 0) return;
45
		
46
		this.data.insertedTokensPtr++;
47
		if(this.data.insertedTokens == null) {
48
			this.data.insertedTokens = new int[10][];
49
			this.data.insertedTokensPosition = new int[10];
50
			this.data.insertedTokenUsed = new boolean[10];
51
		} else if(this.data.insertedTokens.length == this.data.insertedTokensPtr) {
52
			int length = this.data.insertedTokens.length;
53
			System.arraycopy(this.data.insertedTokens, 0, this.data.insertedTokens = new int[length * 2][], 0, length);
54
			System.arraycopy(this.data.insertedTokensPosition, 0, this.data.insertedTokensPosition = new int[length * 2], 0, length);
55
			System.arraycopy(this.data.insertedTokenUsed, 0, this.data.insertedTokenUsed = new boolean[length * 2], 0, length);
56
		}
57
		this.data.insertedTokens[this.data.insertedTokensPtr] = reverse(tokens);
58
		this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
59
		this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
60
	}
61
	
62
	public void replaceTokens(int token, int start, int end) {
63
		replaceTokens(new int []{token}, start, end);
64
	}
65
	
66
	public void replaceTokens(int[] tokens, int start, int end) {
67
		if(!this.record) return;
68
		this.data.replacedTokensPtr++;
69
		if(this.data.replacedTokensStart == null) {
70
			this.data.replacedTokens = new int[10][];
71
			this.data.replacedTokensStart = new int[10];
72
			this.data.replacedTokensEnd = new int[10];
73
			this.data.replacedTokenUsed= new boolean[10];
74
		} else if(this.data.replacedTokensStart.length == this.data.replacedTokensPtr) {
75
			int length = this.data.replacedTokensStart.length;
76
			System.arraycopy(this.data.replacedTokens, 0, this.data.replacedTokens = new int[length * 2][], 0, length);
77
			System.arraycopy(this.data.replacedTokensStart, 0, this.data.replacedTokensStart = new int[length * 2], 0, length);
78
			System.arraycopy(this.data.replacedTokensEnd, 0, this.data.replacedTokensEnd = new int[length * 2], 0, length);
79
			System.arraycopy(this.data.replacedTokenUsed, 0, this.data.replacedTokenUsed = new boolean[length * 2], 0, length);
80
		}
81
		this.data.replacedTokens[this.data.replacedTokensPtr] = reverse(tokens);
82
		this.data.replacedTokensStart[this.data.replacedTokensPtr] = start;
83
		this.data.replacedTokensEnd[this.data.replacedTokensPtr] = end;
84
		this.data.replacedTokenUsed[this.data.replacedTokensPtr] = false;
85
	}
86
	
87
	public void removeTokens(int start, int end) {
88
		if(!this.record) return;
89
		this.data.removedTokensPtr++;
90
		if(this.data.removedTokensStart == null) {
91
			this.data.removedTokensStart = new int[10];
92
			this.data.removedTokensEnd = new int[10];
93
			this.data.removedTokenUsed = new boolean[10];
94
		} else if(this.data.removedTokensStart.length == this.data.removedTokensPtr) {
95
			int length = this.data.removedTokensStart.length;
96
			System.arraycopy(this.data.removedTokensStart, 0, this.data.removedTokensStart = new int[length * 2], 0, length);
97
			System.arraycopy(this.data.removedTokensEnd, 0, this.data.removedTokensEnd = new int[length * 2], 0, length);
98
			System.arraycopy(this.data.removedTokenUsed, 0, this.data.removedTokenUsed = new boolean[length * 2], 0, length);
99
		}
100
		this.data.removedTokensStart[this.data.removedTokensPtr] = start;
101
		this.data.removedTokensEnd[this.data.removedTokensPtr] = end;
102
		this.data.removedTokenUsed[this.data.removedTokensPtr] = false;
103
	}
104
	
105
	public int getNextToken() throws InvalidInputException {
106
		if(this.pendingTokensPtr > -1) {
107
			return this.pendingTokens[this.pendingTokensPtr--];
108
		}
109
		
110
		this.fakeTokenSource = null;
111
		
112
		if(this.data.insertedTokens != null) {
113
//			if(!skipNextInsertedTokens) {
114
				for (int i = 0; i <= this.data.insertedTokensPtr; i++) {
115
					if(this.data.insertedTokensPosition[i] == this.currentPosition - 1 && i > skipNextInsertedTokens) {
116
						this.data.insertedTokenUsed[i] = true;
117
						this.pendingTokens = this.data.insertedTokens[i];
118
						this.pendingTokensPtr = this.data.insertedTokens[i].length - 1;
119
						this.fakeTokenSource = CharOperation.NO_CHAR;
120
						this.startPosition = this.currentPosition - 1;
121
						this.skipNextInsertedTokens = i;
122
						return this.pendingTokens[this.pendingTokensPtr--];
123
					}
124
				}
125
//			}
126
			this.skipNextInsertedTokens = -1;
127
		}
128
129
		int previousLocation = this.currentPosition;
130
		int currentToken = super.getNextToken();
131
		
132
		if(this.data.replacedTokens != null) {
133
			for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
134
				if(this.data.replacedTokensStart[i] >= previousLocation &&
135
						this.data.replacedTokensStart[i] <= this.startPosition &&
136
						this.data.replacedTokensEnd[i] >= this.currentPosition - 1) {
137
					this.data.replacedTokenUsed[i] = true;
138
					this.pendingTokens = this.data.replacedTokens[i];
139
					this.pendingTokensPtr = this.data.replacedTokens[i].length - 1;
140
					this.fakeTokenSource = CharOperation.NO_CHAR;
141
					this.currentPosition = this.data.replacedTokensEnd[i] + 1;
142
					return this.pendingTokens[this.pendingTokensPtr--];
143
				}
144
			}
145
		}
146
		if(this.data.removedTokensStart != null) {
147
			for (int i = 0; i <= this.data.removedTokensPtr; i++) {
148
				if(this.data.removedTokensStart[i] >= previousLocation &&
149
						this.data.removedTokensStart[i] <= this.startPosition &&
150
						this.data.removedTokensEnd[i] >= this.currentPosition - 1) {
151
					this.data.removedTokenUsed[i] = true;
152
					this.currentPosition = this.data.removedTokensEnd[i] + 1;
153
					return getNextToken();
154
				}
155
			}
156
		}
157
		return currentToken;
158
	}
159
	
160
	public char[] getCurrentIdentifierSource() {
161
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
162
		return super.getCurrentIdentifierSource();
163
	}
164
	
165
	public char[] getCurrentTokenSourceString() {
166
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
167
		return super.getCurrentTokenSourceString();
168
	}
169
	
170
	public char[] getCurrentTokenSource() {
171
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
172
		return super.getCurrentTokenSource();
173
	}
174
	
175
	public RecoveryScannerData getData() {
176
		return this.data;
177
	}
178
	
179
	public void setData(RecoveryScannerData data) {
180
		if(data == null) {
181
			this.data = new RecoveryScannerData();
182
		} else {
183
			this.data = data;
184
		}
185
	}
186
}
(-)dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java (+81 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.core.dom;
13
14
import org.eclipse.jdt.core.compiler.IProblem;
15
16
/**
17
 * Internal AST visitor for propagating syntax errors.
18
 */
19
class ASTRecoveryPropagator extends DefaultASTVisitor {
20
	private IProblem[] problems;
21
	
22
	ASTRecoveryPropagator(IProblem[] problems) {
23
		// visit Javadoc.tags() as well
24
		this.problems = problems;
25
	}
26
	
27
	protected boolean visitNode(ASTNode node) {
28
		return checkAndTagAsMalformed(node);
29
	}
30
	
31
	private boolean checkAndTagAsMalformed(ASTNode node) {
32
		boolean tagWithErrors = false;
33
		search: for (int i = 0, max = this.problems.length; i < max; i++) {
34
			IProblem problem = this.problems[i];
35
			switch(problem.getID()) {
36
				case IProblem.ParsingErrorOnKeywordNoSuggestion :
37
				case IProblem.ParsingErrorOnKeyword :
38
				case IProblem.ParsingError :
39
				case IProblem.ParsingErrorNoSuggestion :
40
				case IProblem.ParsingErrorInsertTokenBefore :
41
				case IProblem.ParsingErrorInsertTokenAfter :
42
				case IProblem.ParsingErrorDeleteToken :
43
				case IProblem.ParsingErrorDeleteTokens :
44
				case IProblem.ParsingErrorMergeTokens :
45
				case IProblem.ParsingErrorInvalidToken :
46
				case IProblem.ParsingErrorMisplacedConstruct :
47
				case IProblem.ParsingErrorReplaceTokens :
48
				case IProblem.ParsingErrorNoSuggestionForTokens :
49
				case IProblem.ParsingErrorUnexpectedEOF :
50
				case IProblem.ParsingErrorInsertToComplete :
51
				case IProblem.ParsingErrorInsertToCompleteScope :
52
				case IProblem.ParsingErrorInsertToCompletePhrase :
53
				case IProblem.EndOfSource :
54
				case IProblem.InvalidHexa :
55
				case IProblem.InvalidOctal :
56
				case IProblem.InvalidCharacterConstant :
57
				case IProblem.InvalidEscape :
58
				case IProblem.InvalidInput :
59
				case IProblem.InvalidUnicodeEscape :
60
				case IProblem.InvalidFloat :
61
				case IProblem.NullSourceString :
62
				case IProblem.UnterminatedString :
63
				case IProblem.UnterminatedComment :
64
				case IProblem.InvalidDigit :
65
					break;
66
				default:
67
					continue search;
68
			}
69
			int problemStart = problem.getSourceStart();
70
			int problemEnd = problem.getSourceEnd();
71
			int start = node.getStartPosition();
72
			int end = start + node.getLength();
73
			if ((start <= problemStart) && (problemStart <= end) ||
74
					(start <= problemEnd) && (problemEnd <= end)) {
75
				node.setFlags(node.getFlags() | ASTNode.RECOVERED);
76
				tagWithErrors = true;
77
			}
78
		}
79
		return tagWithErrors;
80
	}
81
}

Return to bug 42253