### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/junit/extension/PerformanceTestSuite.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/junit/extension/PerformanceTestSuite.java,v retrieving revision 1.4 diff -u -r1.4 PerformanceTestSuite.java --- src/org/eclipse/jdt/core/tests/junit/extension/PerformanceTestSuite.java 10 May 2006 18:07:27 -0000 1.4 +++ src/org/eclipse/jdt/core/tests/junit/extension/PerformanceTestSuite.java 13 Nov 2006 10:35:21 -0000 @@ -29,12 +29,12 @@ try { getTestConstructor(theClass); // Avoid generating multiple error messages } catch (NoSuchMethodException e) { - addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()")); + addTest(warningz("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()")); return; } if (!Modifier.isPublic(theClass.getModifiers())) { - addTest(warning("Class "+theClass.getName()+" is not public")); + addTest(warningz("Class "+theClass.getName()+" is not public")); return; } @@ -48,7 +48,7 @@ superClass= superClass.getSuperclass(); } if (countTestCases() == 0) - addTest(warning("No tests found in "+theClass.getName())); + addTest(warningz("No tests found in "+theClass.getName())); } public PerformanceTestSuite(String name) { @@ -61,7 +61,7 @@ return; if (! isPublicTestMethod(m)) { if (isTestMethod(m)) - addTest(warning("Test method isn't public: "+m.getName())); + addTest(warningz("Test method isn't public: "+m.getName())); return; } names.addElement(name); @@ -86,7 +86,7 @@ /** * Returns a test which will fail and log a warning message. */ - private static Test warning(final String message) { + private static Test warningz(final String message) { return new TestCase("warning") { protected void runTest() { fail(message); #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java,v retrieving revision 1.346 diff -u -r1.346 Parser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 29 Mar 2006 02:47:34 -0000 1.346 +++ compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 13 Nov 2006 10:35:26 -0000 @@ -189,6 +189,7 @@ protected TypeDeclaration[] recoveredTypes; protected int recoveredTypePtr; protected int nextTypeStart; + protected TypeDeclaration pendingRecoveredType; public RecoveryScanner recoveryScanner; @@ -1023,6 +1024,17 @@ } } } + + if (this.statementRecoveryActivated) { + if (this.pendingRecoveredType != null && + this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) { + // Add the pending type to the AST if this type isn't already added in the AST. + element = element.add(this.pendingRecoveredType, 0); + this.lastCheckPoint = this.pendingRecoveredType.declarationSourceEnd + 1; + this.pendingRecoveredType = null; + } + } + return element; } @@ -1458,6 +1470,19 @@ this.expressionStack[this.expressionPtr] , this.expressionStack[this.expressionPtr+1], this.scanner.startPosition - 1); + + if (this.pendingRecoveredType != null) { + // Used only in statements recovery. + // This is not a real assignment but a placeholder for an existing anonymous type. + // The assignment must be replace by the anonymous type. + if (this.pendingRecoveredType.allocation != null && + this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) { + this.expressionStack[this.expressionPtr] = this.pendingRecoveredType.allocation; + this.pendingRecoveredType = null; + return; + } + this.pendingRecoveredType = null; + } } protected void consumeAssignmentOperator(int pos) { // AssignmentOperator ::= '=' @@ -6557,6 +6582,19 @@ // break pushs a position on this.intStack in case there is no label pushOnAstStack(new BreakStatement(null, this.intStack[this.intPtr--], this.endPosition)); + + if (this.pendingRecoveredType != null) { + // Used only in statements recovery. + // This is not a real break statement but a placeholder for an existing local type. + // The break statement must be replace by the local type. + if (this.pendingRecoveredType.allocation == null && + this.endPosition <= this.pendingRecoveredType.declarationSourceEnd) { + this.astStack[this.astPtr] = this.pendingRecoveredType; + this.pendingRecoveredType = null; + return; + } + this.pendingRecoveredType = null; + } } protected void consumeStatementBreakWithLabel() { // BreakStatement ::= 'break' Identifier ';' @@ -8515,38 +8553,25 @@ int end = this.scanner.eofPosition; this.scanner.resetTo(typeDeclaration.declarationSourceEnd + 1, end - 1); if(!isAnonymous) { - pushOnAstStack(typeDeclaration); - if(this.astLengthPtr > 0) { - concatNodeLists(); - } - - if(this.currentElement != null) { - this.currentElement = this.currentElement.add(typeDeclaration, 0); - } - - try { - this.currentToken = this.scanner.getNextToken(); - } catch(InvalidInputException e){ - if (!this.hasReportedError){ - this.problemReporter().scannerError(this, e.getMessage()); - this.hasReportedError = true; - } - this.lastCheckPoint = this.scanner.currentPosition; - } + ((RecoveryScanner)this.scanner).setPendingTokens(new int[]{TokenNameSEMICOLON, TokenNamebreak}); } else { - if(this.astPtr > -1 && this.astStack[this.astPtr] instanceof TypeDeclaration) { - this.astStack[astPtr] = typeDeclaration; - this.expressionStack[this.expressionPtr] = typeDeclaration.allocation; - } - this.currentToken = TokenNameRBRACE; + ((RecoveryScanner)this.scanner).setPendingTokens(new int[]{TokenNameIdentifier, TokenNameEQUAL, TokenNameIdentifier}); + } + + this.pendingRecoveredType = typeDeclaration; + + try { + this.currentToken = this.scanner.getNextToken(); + } catch(InvalidInputException e){ + // it's impossible because we added pending tokens before } if(++this.recoveredTypePtr < this.recoveredTypes.length) { TypeDeclaration nextTypeDeclaration = this.recoveredTypes[this.recoveredTypePtr]; this.nextTypeStart = nextTypeDeclaration.allocation == null - ? nextTypeDeclaration.declarationSourceStart - : nextTypeDeclaration.bodyStart; + ? nextTypeDeclaration.declarationSourceStart + : nextTypeDeclaration.allocation.sourceStart; } else { this.nextTypeStart = Integer.MAX_VALUE; } @@ -8757,7 +8782,6 @@ protected void parse() { if (DEBUG) System.out.println("-- ENTER INSIDE PARSE METHOD --"); //$NON-NLS-1$ boolean isDietParse = this.diet; - boolean jumpOverTypeAfterReduce = false; int oldFirstToken = getFirstToken(); this.hasError = false; @@ -8808,7 +8832,7 @@ this.restartRecovery = true; } if(this.statementRecoveryActivated) { - jumpOverTypeAfterReduce = true; + this.jumpOverType(); } act -= ERROR_ACTION; @@ -8839,12 +8863,6 @@ consumeRule(act); this.stateStackTop -= (rhs[act] - 1); act = ntAction(this.stack[this.stateStackTop], lhs[act]); - if(this.statementRecoveryActivated && act > NUM_RULES) { - if(jumpOverTypeAfterReduce) { - this.jumpOverType(); - jumpOverTypeAfterReduce = false; - } - } } while (act <= NUM_RULES); } endParse(act); @@ -9292,13 +9310,15 @@ this.referenceContext = rc; this.compilationUnit = unit; + this.pendingRecoveredType = null; + if(types != null && types.length > 0) { this.recoveredTypes = types; this.recoveredTypePtr = 0; this.nextTypeStart = this.recoveredTypes[0].allocation == null ? this.recoveredTypes[0].declarationSourceStart - : this.recoveredTypes[0].bodyStart; + : this.recoveredTypes[0].allocation.sourceStart; } else { this.recoveredTypes = null; this.recoveredTypePtr = -1; @@ -9900,6 +9920,8 @@ if (this.currentElement == null){ // Reset javadoc before restart parsing after recovery this.javadoc = null; + + if (this.statementRecoveryActivated) return false; // build some recovered elements this.currentElement = buildInitialRecoveryState(); Index: compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java,v retrieving revision 1.7 diff -u -r1.7 RecoveryScanner.java --- compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java 27 Feb 2006 17:24:27 -0000 1.7 +++ compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java 13 Nov 2006 10:35:26 -0000 @@ -233,4 +233,9 @@ this.data = data; } } + + public void setPendingTokens(int[] pendingTokens) { + this.pendingTokens = pendingTokens; + this.pendingTokensPtr = pendingTokens.length - 1; + } }