Bug 506888 - Unused @SuppressWarnings("incomplete-switch") not reported
- fixed passing of optionId to UI
- fixed mapping of UnusedDeclaredThrownException
- opportunistically exclude MissingNonNullByDefaultAnnotation
- follow-up adjustments in tests


Change-Id: I645a394946b8f496c0905f193f2939308a8e2424
Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 2db2c29..ee6196c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -82,6 +82,7 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
@@ -1152,6 +1153,23 @@
 		return defaultOptions;
 	}
 
+	protected void enableAllWarningsForIrritants(Map<String, String> options, IrritantSet irritants) {
+		int[] bits = irritants.getBits();
+		for (int i = 0; i < bits.length; i++) {
+			int bit = bits[i];
+			for (int b = 0; b < IrritantSet.GROUP_SHIFT; b++) {
+				int single = bit & (1 << b);
+				if (single != 0) {
+					single |= (i<<IrritantSet.GROUP_SHIFT);
+					if (single == CompilerOptions.MissingNonNullByDefaultAnnotation)
+						continue;
+					String optionKey = CompilerOptions.optionKeyFromIrritant(single);
+					options.put(optionKey, CompilerOptions.WARNING);
+				}
+			}
+		}
+	}
+
 	protected String[] getDefaultClassPaths() {
 		return DefaultJavaRuntimeEnvironment.getDefaultClassPaths();
 	}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
index 060df16..b2244d9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
@@ -34,10 +34,14 @@
 
 import junit.framework.Test;
 
+import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
 import org.eclipse.jdt.core.tests.util.Util;
 import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
 import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
 import org.eclipse.jdt.internal.compiler.IProblemFactory;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -49,6 +53,7 @@
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
@@ -7689,6 +7694,7 @@
 public void test230() {
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.ERROR);
+	enableAllWarningsForIrritants(options, IrritantSet.UNUSED);
 	this.runNegativeTest(
 		true,
 		new String[] {
@@ -7727,6 +7733,7 @@
 public void test231() {
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.ERROR);
+	enableAllWarningsForIrritants(options, IrritantSet.UNUSED);
 	this.runNegativeTest(
 		true,
 		new String[] {
@@ -8119,6 +8126,7 @@
 	options.put(CompilerOptions.OPTION_ReportUncheckedTypeOperation, CompilerOptions.IGNORE);
 	options.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE);
 	options.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.WARNING);
+	enableAllWarningsForIrritants(options, IrritantSet.UNUSED);
 	this.runNegativeTest(
 		true,
 		new String[] {
@@ -10199,6 +10207,7 @@
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437
 public void testBug365437a() {
 	Map customOptions = getCompilerOptions();
+	enableAllWarningsForIrritants(customOptions, IrritantSet.NULL);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	String testFiles [] = new String[] {
 			"p/A.java",
@@ -10297,6 +10306,7 @@
 public void testBug365437c() {
 	if (this.complianceLevel < ClassFileConstants.JDK1_7) return;
 	Map customOptions = getCompilerOptions();
+	enableAllWarningsForIrritants(customOptions, IrritantSet.NULL);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	String testFiles [] = new String[] {
 			"p/A.java",
@@ -10346,6 +10356,7 @@
 // unused constructor
 public void testBug365437d() {
 	Map customOptions = getCompilerOptions();
+	enableAllWarningsForIrritants(customOptions, IrritantSet.NULL);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED);
@@ -10425,6 +10436,7 @@
 // unused field
 public void testBug365437e() {
 	Map customOptions = getCompilerOptions();
+	enableAllWarningsForIrritants(customOptions, IrritantSet.NULL);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED);
@@ -10497,6 +10509,7 @@
 // unused type
 public void testBug365437f() {
 	Map customOptions = getCompilerOptions();
+	enableAllWarningsForIrritants(customOptions, IrritantSet.NULL);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
 	customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED);
@@ -11770,4 +11783,58 @@
 		"", 
 		null, true, options);
 }
+public void testBug506888f() throws Exception {
+
+	class MyCompilerRequestor implements ICompilerRequestor {
+		String[] problemArguments = null;
+
+		@Override
+		public void acceptResult(CompilationResult result) {
+			for (CategorizedProblem problem : result.getAllProblems()) {
+				String[] arguments = problem.getArguments();
+				if (arguments != null && arguments.length > 0) {
+					this.problemArguments = arguments;
+					return;
+				}
+			}
+		}
+	}
+
+	if (this.complianceLevel <= ClassFileConstants.JDK1_5) {
+		return;
+	}
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportUnusedWarningToken, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, CompilerOptions.IGNORE);
+	options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING);
+	MyCompilerRequestor requestor = new MyCompilerRequestor();
+	runTest(new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	\n" +
+				"	@SuppressWarnings({\"unused\"})\n" +
+				"	void foo() {\n" +
+				"	}\n" +
+				"}	\n",
+			},
+			false,
+			"----------\n" + 
+			"1. INFO in X.java (at line 3)\n" + 
+			"	@SuppressWarnings({\"unused\"})\n" + 
+			"	                   ^^^^^^^^\n" + 
+			"At least one of the problems in category \'unused\' is not analysed due to a compiler option being ignored\n" + 
+			"----------\n",
+			"" /*expectedOutputString */,
+			"" /* expectedErrorString */,
+			false /* forceExecution */,
+			null /* classLib */,
+			true /* shouldFlushOutputDirectory */,
+			null /* vmArguments */,
+			options,
+			new Requestor(true, requestor, false, true),
+			JavacTestOptions.DEFAULT);
+	assertNotNull(requestor.problemArguments);
+	assertEquals(1, requestor.problemArguments.length);
+	assertEquals(JavaCore.COMPILER_PB_UNUSED_PARAMETER, requestor.problemArguments[0]);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index a6b7201..a5d68e3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -11668,7 +11668,7 @@
 		"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" + 
 		"	@SuppressWarnings(\"unused\")\n" + 
 		"	                  ^^^^^^^^\n" + 
-		"Unnecessary @SuppressWarnings(\"unused\")\n" + 
+		"At least one of the problems in category 'unused' is not analysed due to a compiler option being ignored\n" + 
 		"----------\n" + 
 		"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" + 
 		"	private int i;\n" + 
@@ -11759,7 +11759,7 @@
 		"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" + 
 		"	@SuppressWarnings(\"unused\")\n" + 
 		"	                  ^^^^^^^^\n" + 
-		"Unnecessary @SuppressWarnings(\"unused\")\n" + 
+		"At least one of the problems in category 'unused' is not analysed due to a compiler option being ignored\n" + 
 		"----------\n" + 
 		"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 3)\n" + 
 		"	private int i;\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index fe3f0ac..4c28907 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -1905,10 +1905,10 @@
 		expectedProblemAttributes.put("UnsafeTypeConversion", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
 		expectedProblemAttributes.put("UnterminatedComment", SKIP);
 		expectedProblemAttributes.put("UnterminatedString", SKIP);
-		expectedProblemAttributes.put("UnusedConstructorDeclaredThrownException", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING));
+		expectedProblemAttributes.put("UnusedConstructorDeclaredThrownException", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION));
 		expectedProblemAttributes.put("UnusedImport", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_IMPORT));
 		expectedProblemAttributes.put("UnusedLabel", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_LABEL));
-		expectedProblemAttributes.put("UnusedMethodDeclaredThrownException", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING));
+		expectedProblemAttributes.put("UnusedMethodDeclaredThrownException", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION));
 		expectedProblemAttributes.put("UnusedObjectAllocation", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_OBJECT_ALLOCATION));
 		expectedProblemAttributes.put("UnusedPrivateConstructor", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER));
 		expectedProblemAttributes.put("UnusedPrivateField", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index 055ab74..3939590 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -24,6 +24,7 @@
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
 
 @SuppressWarnings({ "unchecked", "rawtypes" })
 public class ResourceLeakTests extends AbstractRegressionTest {
@@ -266,6 +267,7 @@
 public void test056d_suppress() {
 	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // annotations used
 	Map options = getCompilerOptions();
+	enableAllWarningsForIrritants(options, IrritantSet.RESOURCE);
 	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
 	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
 	options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index b53db57..22c2272 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -607,7 +607,7 @@
 			case UnqualifiedFieldAccess :
 				return OPTION_ReportUnqualifiedFieldAccess;
 			case UnusedDeclaredThrownException :
-				return OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding;
+				return OPTION_ReportUnusedDeclaredThrownException;
 			case FinallyBlockNotCompleting :
 				return OPTION_ReportFinallyBlockNotCompletingNormally;
 			case InvalidJavadoc :
@@ -1277,10 +1277,15 @@
 		int[] bits = irritants.getBits();
 		for (int i = 0; i < IrritantSet.GROUP_MAX; i++) {
 			int bit = bits[i];
-			if (bit > 0) {
-				bit |= (i << IrritantSet.GROUP_SHIFT);
-				if (!(this.warningThreshold.isSet(bit) || this.errorThreshold.isSet(bit) || this.infoThreshold.isSet(bit))) {
-					return bit;
+			for (int b = 0; b < IrritantSet.GROUP_SHIFT; b++) {
+				int single = bit & (1 << b);
+				if (single > 0) {
+					single |= (i << IrritantSet.GROUP_SHIFT);
+					if (single == MissingNonNullByDefaultAnnotation)
+						continue;
+					if (!(this.warningThreshold.isSet(single) || this.errorThreshold.isSet(single) || this.infoThreshold.isSet(single))) {
+						return single;
+					}
 				}
 			}
 		}