### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java,v retrieving revision 1.65 diff -u -r1.65 CompilationResult.java --- compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java 11 May 2010 18:47:09 -0000 1.65 +++ compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java 4 May 2011 17:39:39 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -72,6 +72,7 @@ public boolean hasSyntaxError = false; public char[][] packageName; public boolean checkSecondaryTypes = false; // check for secondary types which were created after the initial buildTypeBindings call + public int numberOfErrors; private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY; private static final Comparator PROBLEM_COMPARATOR = new Comparator() { @@ -270,12 +271,7 @@ } public boolean hasErrors() { - if (this.problems != null) - for (int i = 0; i < this.problemCount; i++) { - if (this.problems[i].isError()) - return true; - } - return false; + return this.numberOfErrors != 0; } public boolean hasProblems() { @@ -345,8 +341,12 @@ if (newProblem.isError() && !referenceContext.hasErrors()) this.firstErrors.add(newProblem); this.problemsMap.put(newProblem, referenceContext); } - if ((newProblem.getID() & IProblem.Syntax) != 0 && newProblem.isError()) - this.hasSyntaxError = true; + if (newProblem.isError()) { + this.numberOfErrors++; + if ((newProblem.getID() & IProblem.Syntax) != 0) { + this.hasSyntaxError = true; + } + } } /** Index: compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java,v retrieving revision 1.91 diff -u -r1.91 CompilationUnitDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java 25 Jun 2010 14:58:36 -0000 1.91 +++ compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java 4 May 2011 17:39:39 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,6 +16,7 @@ import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.ASTVisitor; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.CompilationResult; @@ -207,24 +208,56 @@ } public void finalizeProblems() { - if (this.suppressWarningsCount == 0) return; + if (this.suppressWarningsCount == 0) { + if (this.compilationResult.hasErrors()) { + // we need to check if we should discard unused locals warnings + int removed = 0; + CategorizedProblem[] problems = this.compilationResult.problems; + int problemCount = this.compilationResult.problemCount; + for (int i = 0; i < problemCount; i++) { + if (problems[i].getID() == IProblem.LocalVariableIsNeverUsed) { + problems[i] = null; + removed++; + } + } + // compact remaining problems + if (removed > 0) { + for (int i = 0, index = 0; i < problemCount; i++) { + CategorizedProblem problem; + if ((problem = problems[i]) != null) { + if (i > index) { + problems[index++] = problem; + } else { + index++; + } + } + } + this.compilationResult.problemCount -= removed; + } + } + return; + } int removed = 0; CategorizedProblem[] problems = this.compilationResult.problems; int problemCount = this.compilationResult.problemCount; IrritantSet[] foundIrritants = new IrritantSet[this.suppressWarningsCount]; CompilerOptions options = this.scope.compilerOptions(); boolean hasMandatoryErrors = false; + int remainingErrors = 0; nextProblem: for (int iProblem = 0, length = problemCount; iProblem < length; iProblem++) { CategorizedProblem problem = problems[iProblem]; int problemID = problem.getID(); int irritant = ProblemReporter.getIrritant(problemID); - if (problem.isError()) { + boolean isError = problem.isError(); + if (isError) { if (irritant == 0) { // tolerate unused warning tokens when mandatory errors hasMandatoryErrors = true; + remainingErrors++; continue; } if (!options.suppressOptionalErrors) { + remainingErrors++; continue; } } @@ -234,13 +267,21 @@ long position = this.suppressWarningScopePositions[iSuppress]; int startSuppress = (int) (position >>> 32); int endSuppress = (int) position; - if (start < startSuppress) continue nextSuppress; - if (end > endSuppress) continue nextSuppress; - if (!this.suppressWarningIrritants[iSuppress].isSet(irritant)) + if (start < startSuppress) { continue nextSuppress; + } + if (end > endSuppress) { + continue nextSuppress; + } + if (!this.suppressWarningIrritants[iSuppress].isSet(irritant)) { + continue nextSuppress; + } // discard suppressed warning removed++; problems[iProblem] = null; + if (isError) { + this.compilationResult.numberOfErrors--; + } if (this.compilationResult.problemsMap != null) this.compilationResult.problemsMap.remove(problem); if (this.compilationResult.firstErrors != null) this.compilationResult.firstErrors.remove(problem); if (foundIrritants[iSuppress] == null){ @@ -250,6 +291,19 @@ } continue nextProblem; } + if (isError) { + remainingErrors++; + } + } + // we need to check if we should discard unused locals warnings that were not already filtered out + if (remainingErrors > 0) { + for (int i = 0; i < problemCount; i++) { + CategorizedProblem problem; + if ((problem = problems[i]) != null && problem.getID() == IProblem.LocalVariableIsNeverUsed) { + problems[i] = null; + removed++; + } + } } // compact remaining problems if (removed > 0) { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java,v retrieving revision 1.124 diff -u -r1.124 BlockScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java 16 Feb 2011 08:09:18 -0000 1.124 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java 4 May 2011 17:39:39 -0000 @@ -199,10 +199,7 @@ && ((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { // declaration is reachable if (!(local.declaration instanceof Argument)) // do not report unused catch arguments - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=336648 - if (!this.referenceCompilationUnit().compilationResult.hasErrors()) { - problemReporter().unusedLocalVariable(local.declaration); - } + problemReporter().unusedLocalVariable(local.declaration); } // could be optimized out, but does need to preserve unread variables ? #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java,v retrieving revision 1.221 diff -u -r1.221 AnnotationTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java 14 Mar 2011 21:14:23 -0000 1.221 +++ src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java 4 May 2011 17:39:40 -0000 @@ -46,7 +46,7 @@ // All specified tests which do not belong to the class are skipped... static { // TESTS_NAMES = new String[] { "test293" }; -// TESTS_NUMBERS = new int[] { 294 }; +// TESTS_NUMBERS = new int[] { 297 }; // TESTS_RANGE = new int[] { 294, -1 }; } @@ -9789,4 +9789,45 @@ customOptions, null); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=343621 +public void test297() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_SuppressWarnings, CompilerOptions.ENABLED); + customOptions.put(CompilerOptions.OPTION_ReportUnhandledWarningToken, CompilerOptions.WARNING); + customOptions.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED); + customOptions.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING); + customOptions.put(CompilerOptions.OPTION_ReportComparingIdentical, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportUncheckedTypeOperation, CompilerOptions.ERROR); + String testFiles [] = new String[] { + "A.java", + "public class A {\n" + + " public void one() {\n" + + " @SuppressWarnings(\"unused\")\n" + + " Object object = new Object();\n" + + " }\n" + + " public void two() {\n" + + " @SuppressWarnings({ \"unchecked\", \"unused\" })\n" + + " Object object = build();\n" + + " }\n" + + " public final Object build(Class... objects) {\n" + + " return null;\n" + + " }\n" + + " public boolean bar() {\n" + + " int i = 0;\n" + + " return i == i;\n" + + " }\n" + + "}" + }; + runNegativeTest( + testFiles, + "----------\n" + + "1. ERROR in A.java (at line 15)\n" + + " return i == i;\n" + + " ^^^^^^\n" + + "Comparing identical expressions\n" + + "----------\n", + null, + true, + customOptions); +} }