Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2011-10-25 16:30:36 +0000
committerStephan Herrmann2011-10-25 16:30:36 +0000
commit71432c0b3a7c9ea06e15185063ebff50c33d4643 (patch)
treee29b0104f05d122101a93d144c89c7ad8aa821d1 /org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core
parent6dcbb38068eee59acb310076b78bc9a8183f88b8 (diff)
downloadorg.eclipse.objectteams-71432c0b3a7c9ea06e15185063ebff50c33d4643.tar.gz
org.eclipse.objectteams-71432c0b3a7c9ea06e15185063ebff50c33d4643.tar.xz
org.eclipse.objectteams-71432c0b3a7c9ea06e15185063ebff50c33d4643.zip
update sources to v_C18, build config to v_C17 (no build containing C18 is available at this point)
Diffstat (limited to 'org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core')
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java15
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java4
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java135
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java74
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java16
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java132
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java78
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java466
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java112
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java205
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java176
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java1806
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java4
16 files changed, 3110 insertions, 119 deletions
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 8ff3a9e18..8c518e8b8 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
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
+import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@@ -32,8 +33,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
+import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
@@ -2781,4 +2784,16 @@ protected void runNegativeTest(
printJavacResultsSummary();
}
}
+ /**
+ * Returns the OS path to the directory that contains this plugin.
+ */
+ protected String getCompilerTestsPluginDirectoryPath() {
+ try {
+ URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.compiler").getEntry("/");
+ return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java
index 42ccda452..72307e8b2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 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
@@ -1221,7 +1221,7 @@ public void test050() {
"1. ERROR in p\\X.java (at line 4)\n" +
" public static String s;\n" +
" ^\n" +
- "The field s cannot be declared static; static fields can only be declared in static or top level types\n" +
+ "The field s cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" +
"----------\n" +
"2. ERROR in p\\X.java (at line 6)\n" +
" X.XX.s = s; }\n" +
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 f15f9de6a..ec8197cff 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
@@ -8,9 +8,12 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Muskalla - Contribution for bug 239066
- * Stephan Herrmann - Contribution for bug 236385
- * Stephan Herrmann - Contribution for bug 295551
- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ * bug 295551 - Add option to automatically promote all warnings to errors
+ * bug 185682 - Increment/decrement operators mark local variables as read
+ * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 359721 - [options] add command line option for new warning token "resource"
* Technical University Berlin - adapted for Object Teams
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1669,6 +1672,7 @@ public void test012b(){
//OT (2x):
" abstractrelevantrole + abstract relevant role (OTJLD 2.5(b))\n" +
" adaptDeprecated + adapting a deprecated type/method\n" +
+ " all enable all warnings\n" +
" allDeadCode dead code including trivial if(DEBUG) check\n" +
" allDeprecation deprecation including inside deprecated code\n" +
" allJavadoc invalid or missing javadoc\n" +
@@ -1740,6 +1744,7 @@ public void test012b(){
" paramAssign assignment to a parameter\n" +
" pkgDefaultMethod + attempt to override package-default method\n" +
" raw + usage of raw type\n" +
+ " resource + (pot.) unsafe usage of resource of type Closeable\n" +
//OT:
" roleinstantiation + unsafe instantiation of a role\n" +
" (OTJLD 2.4.1(c), 2.4.3)\n" +
@@ -1861,6 +1866,7 @@ public void test012b(){
" <option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" +
@@ -1902,6 +1908,7 @@ public void test012b(){
" <option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" +
@@ -1917,6 +1924,7 @@ public void test012b(){
" <option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" +
@@ -6942,7 +6950,7 @@ public void test174_warn_options() {
"3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" +
" } catch (E1 e1) {\n" +
" ^^\n" +
- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"3 problems (3 warnings)",
true);
@@ -7010,7 +7018,7 @@ public void test175_warn_options() {
"4. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" +
" } catch (E1 e1) {\n" +
" ^^\n" +
- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"4 problems (4 warnings)",
true);
@@ -7145,7 +7153,7 @@ public void test178_warn_options() {
"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" +
" } catch (E1 e1) {\n" +
" ^^\n" +
- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"1 problem (1 warning)",
true);
@@ -7245,7 +7253,7 @@ public void test180_warn_options() {
"3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" +
" } catch (E1 e1) {\n" +
" ^^\n" +
- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"3 problems (3 warnings)",
true);
@@ -7300,7 +7308,7 @@ public void test181_warn_options() {
"3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" +
" } catch (E1 e1) {\n" +
" ^^\n" +
- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"3 problems (3 warnings)",
true);
@@ -7410,7 +7418,7 @@ public void test183_warn_options() {
"3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" +
" } catch (E1 e1) {\n" +
" ^^\n" +
- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"3 problems (3 warnings)",
true);
@@ -8580,48 +8588,6 @@ public void test213_warn_options() {
"1 problem (1 warning)",
true);
}
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=210518
-// variant
-public void test214_warn_options() {
- // same source as 153, skip default checks
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " public static void foo() {\n" +
- " String s = null;\n" +
- " s.toString();\n" +
- " String u;\n" +
- " }\n" +
- "}",
- },
- "\"" + OUTPUT_DIR + File.separator + "X.java\""
- + " -warn:null,-unused -proc:none -d \"" + OUTPUT_DIR + "\"",
- "",
- "usage of \'-\' for \'-unused\' is illegal there\n",
- true);
-}
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=210518
-// variant
-public void test215_warn_options() {
- // same source as 153, skip default checks
- this.runNegativeTest(
- new String[] {
- "X.java",
- "public class X {\n" +
- " public static void foo() {\n" +
- " String s = null;\n" +
- " s.toString();\n" +
- " String u;\n" +
- " }\n" +
- "}",
- },
- "\"" + OUTPUT_DIR + File.separator + "X.java\""
- + " -warn:null,+unused -proc:none -d \"" + OUTPUT_DIR + "\"",
- "",
- "usage of \'+\' for \'+unused\' is illegal there\n",
- true);
-}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=211588
// variant - check impact of javadoc upon other warnings
public void _test216a_warn_options() {
@@ -11468,24 +11434,6 @@ public void test294(){
true);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784
-public void test295(){
- this.runNegativeTest(
- new String[] {
- "src/X.java",
- "public class X {\n" +
- "}",
- },
- "\"" + OUTPUT_DIR + File.separator + "src/X.java\""
- + " -cp \"" + LIB_DIR + "\""
- + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\""
- + " -1.5 -g -preserveAllLocals"
- + " -proceedOnError -referenceInfo -err:raw,+discouraged"
- + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ",
- "",
- "usage of \'+\' for \'+discouraged\' is illegal there\n",
- true);
-}
-//https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784
public void test296(){
this.runNegativeTest(
new String[] {
@@ -12365,4 +12313,53 @@ public void testReportingUnavoidableGenericProblems2() {
"3 problems (1 error, 2 warnings)",
true);
}
+//-warn option - regression tests
+public void test0308_warn_options() {
+ // check the option introduced in bug 359721
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo() throws java.io.IOException {\n" +
+ " FileReader r = new FileReader(\"f1\");\n" +
+ " char[] cs = new char[1024];\n" +
+ " r.read(cs);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "X.java\""
+ + " -warn:-resource -1.7 -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "",
+ true);
+}
+//-warn option - regression tests
+public void test0309_warn_options() {
+ // check the option introduced in bug 359721
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo(boolean b) throws java.io.IOException {\n" +
+ " FileReader r = new FileReader(\"f1\");\n" +
+ " char[] cs = new char[1024];\n" +
+ " r.read(cs);\n" +
+ " if (b) r.close();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "X.java\""
+ + " -warn:+resource -1.7 -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "----------\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 4)\n" +
+ " FileReader r = new FileReader(\"f1\");\n" +
+ " ^\n" +
+ "Potential resource leak: \'r\' may not be closed\n" +
+ "----------\n" +
+ "1 problem (1 warning)",
+ true);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java
new file mode 100644
index 000000000..15d6b0155
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.io.File;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+
+public class BootstrapMethodAttributeTest extends AbstractRegressionTest {
+ public BootstrapMethodAttributeTest(String name) {
+ super(name);
+ }
+
+ public static Class testClass() {
+ return BootstrapMethodAttributeTest.class;
+ }
+
+ // Use this static initializer to specify subset for tests
+ // All specified tests which does not belong to the class are skipped...
+ static {
+// TESTS_PREFIX = "testBug95521";
+// TESTS_NAMES = new String[] { "testBug359495" };
+// TESTS_NUMBERS = new int[] { 53 };
+// TESTS_RANGE = new int[] { 23 -1,};
+ }
+ public static Test suite() {
+ return buildMinimalComplianceTestSuite(testClass(), F_1_7);
+ }
+ public void test001() throws Exception {
+
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ String path = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "TestBootstrapMethodAtt.class";
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(path));
+ String actualOutput =
+ disassembler.disassemble(
+ classFileBytes,
+ "\n",
+ ClassFileBytesDisassembler.DETAILED);
+
+ String expectedOutput =
+ "// (version 1.2 : 46.0, no super bit)\n" +
+ "public class test.G {\n" +
+ " \n" +
+ " // Method descriptor #2 ()V\n" +
+ " // Stack: 0, Locals: 0\n" +
+ " public static void call();\n" +
+ " 0 invokedynamic 0 dyn() : void [18]\n" +
+ " 5 return\n" +
+ "\n" +
+ "Bootstrap methods:\n" +
+ " 0 : # 17 arguments: {#1}\n" +
+ "}";
+
+ int index = actualOutput.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(actualOutput, 2));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, actualOutput);
+ }
+ }
+}
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 e43338151..bbd1f0705 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
@@ -8,7 +8,9 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Muskalla - Contribution for bug 239066
- * Stephan Herrmann - Contribution for bug 236385
+ * Stephan Herrmann - Contributions for
+ * bug 236385: [compiler] Warn for potential programming problem if an object is created but not used
+ * bug 349326 - [1.7] new warning for missing try-with-resources
* Stephan Herrmann - Adjustments for Object Teams
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -444,6 +446,7 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED);
expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED);
expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED);
+ expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
@@ -769,6 +772,8 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
+ expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
@@ -808,6 +813,7 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("SuperclassNotFound", DEPRECATED);
expectedProblemAttributes.put("SuperclassNotVisible", DEPRECATED);
expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("SwitchOnEnumNotBelow15", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("SwitchOnStringsNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("Task", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("ThisInStaticContext", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
@@ -832,6 +838,8 @@ public void _test011_problem_categories() {
expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT));
expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
+ expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
@@ -1193,6 +1201,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP);
expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP);
expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP);
+ expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE));
expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP);
expectedProblemAttributes.put("ExternalProblemFixable", SKIP);
expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP);
@@ -1518,6 +1527,8 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP);
expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
+ expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
+ expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
@@ -1557,6 +1568,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("SuperclassNotFound", SKIP);
expectedProblemAttributes.put("SuperclassNotVisible", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_SUPERINTERFACE));
expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(JavaCore.COMPILER_PB_EMPTY_STATEMENT));
+ expectedProblemAttributes.put("SwitchOnEnumNotBelow15", SKIP);
expectedProblemAttributes.put("SwitchOnStringsNotBelow17", SKIP);
expectedProblemAttributes.put("Task", SKIP);
expectedProblemAttributes.put("ThisInStaticContext", SKIP);
@@ -1581,6 +1593,8 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION));
expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING));
expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING));
+ expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE));
+ expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE));
expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP);
expectedProblemAttributes.put("UndefinedConstructor", SKIP);
expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
index 66eeb0d6c..f63a0609a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
@@ -1119,7 +1119,7 @@ public void test020() {
"1. ERROR in X.java (at line 4)\n" +
" static final String notAConstant = null;\n" +
" ^^^^^^^^^^^^\n" +
- "The field notAConstant cannot be declared static; static fields can only be declared in static or top level types\n" +
+ "The field notAConstant cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" +
"----------\n");
}
public void testAllConstants() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java
index b9f580f25..aa4d4729e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java
@@ -3761,7 +3761,7 @@ public void test113() {
"1. ERROR in X.java (at line 3)\n" +
" static int bar;\n" +
" ^^^\n" +
- "The field bar cannot be declared static; static fields can only be declared in static or top level types\n" +
+ "The field bar cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=99428 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=99655
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
index 32b50af3e..f197e7dab 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
@@ -7,7 +7,10 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 236385
+ * Stephan Herrmann - Contributions for
+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -28,6 +31,7 @@ import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
public class FlowAnalysisTest extends AbstractRegressionTest {
static {
+// TESTS_NAMES = new String[] { "testLocalClassInInitializer1" };
// TESTS_NUMBERS = new int[] { 69 };
}
public FlowAnalysisTest(String name) {
@@ -2360,6 +2364,132 @@ public void testBug338234d() {
"The local variable i may not have been initialized\n" +
"----------\n");
}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// variant < 1.7 using Closeable: not closed
+public void testCloseable1() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file); // not closed\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file); // not closed\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is never closed\n" +
+ "----------\n");
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// variant < 1.7 using Closeable: resource is closed, cannot suggest try-with-resources < 1.7
+public void testCloseable2() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file); // not closed\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+// return/break/continue inside anonymous class inside try-catch inside initializer
+public void testLocalClassInInitializer1() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " static {\n" +
+ " final int i=4;\n" +
+ " try {\n" +
+ " Runnable runner = new Runnable() {\n" +
+ " public void run() {\n" +
+ " switch (i) {" +
+ " case 4: break;\n" +
+ " }\n" +
+ " int j = i;\n" +
+ " while (j++ < 10) {\n" +
+ " if (j == 2) continue;\n" +
+ " if (j == 4) break;\n" +
+ " if (j == 6) return;\n" +
+ " }\n" +
+ " }\n" +
+ " };\n" +
+ " } catch (RuntimeException re) {}\n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+// break/continue illegally inside anonymous class inside loop (loop is out of scope for break/continue)
+public void testLocalClassInInitializer2() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void f () {\n" +
+ " while (true) {\n" +
+ " class Inner1 {\n" +
+ " { if (true) break; }\n" +
+ " }\n" +
+ " new Inner1();\n" +
+ " }\n" +
+ " } \n" +
+ " void g () {\n" +
+ " outer: for (int i=1;true;i++) {\n" +
+ " class Inner2 {\n" +
+ " int j = 3;\n" +
+ " void foo () {\n" +
+ " if (2 == j) continue outer;\n" +
+ " else continue;\n" +
+ " }\n" +
+ " }\n" +
+ " new Inner2().foo();\n" +
+ " }\n" +
+ " } \n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " { if (true) break; }\n" +
+ " ^^^^^^\n" +
+ "break cannot be used outside of a loop or a switch\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 11)\n" +
+ " outer: for (int i=1;true;i++) {\n" +
+ " ^^^^^\n" +
+ "The label outer is never explicitly referenced\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 15)\n" +
+ " if (2 == j) continue outer;\n" +
+ " ^^^^^^^^^^^^^^^\n" +
+ "The label outer is missing\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 16)\n" +
+ " else continue;\n" +
+ " ^^^^^^^^^\n" +
+ "continue cannot be used outside of a loop\n" +
+ "----------\n");
+}
public static Class testClass() {
return FlowAnalysisTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index 56c50ae67..f1d190bbb 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -11238,25 +11238,7 @@ public void test199() {
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=285088
public void test200() {
- Map options = getCompilerOptions();
- String compliance = (String) options.get(JavaCore.COMPILER_COMPLIANCE);
- String errorMessage = compliance == JavaCore.VERSION_1_6 ?
- "----------\n" +
- "1. WARNING in X.java (at line 3)\n" +
- " int foo(Collection bar) { return 0; }\n" +
- " ^^^^^^^^^^^^^^^^^^^\n" +
- "Method foo(Collection) has the same erasure foo(Collection<E>) as another method in type X\n" +
- "----------\n" +
- "2. WARNING in X.java (at line 3)\n" +
- " int foo(Collection bar) { return 0; }\n" +
- " ^^^^^^^^^^\n" +
- "Collection is a raw type. References to generic type Collection<E> should be parameterized\n" +
- "----------\n" +
- "3. WARNING in X.java (at line 4)\n" +
- " double foo(Collection<String> bar) {return 0; }\n" +
- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
- "Method foo(Collection<String>) has the same erasure foo(Collection<E>) as another method in type X\n" +
- "----------\n" :
+ String errorMessage =
"----------\n" +
"1. ERROR in X.java (at line 3)\n" +
" int foo(Collection bar) { return 0; }\n" +
@@ -13439,7 +13421,7 @@ public void testBug317719h() throws Exception {
String output = this.complianceLevel == ClassFileConstants.JDK1_6 ?
"----------\n" +
"1. WARNING in Test.java (at line 3)\n" +
- " public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" +
+ " public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" +
" ^^^^\n" +
"The serializable class Test does not declare a static final serialVersionUID field of type long\n" +
"----------\n" +
@@ -13451,7 +13433,7 @@ public void testBug317719h() throws Exception {
"3. WARNING in Test.java (at line 5)\n" +
" public Collection<Value> get(Key k) { return null; }\n" +
" ^^^^^^^^^^\n" +
- "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type LinkedHashMap<K,V> but does not override it\n" +
+ "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type HashMap<K,V> but does not override it\n" +
"----------\n" +
"4. ERROR in Test.java (at line 6)\n" +
" Zork z;\n" +
@@ -13460,7 +13442,7 @@ public void testBug317719h() throws Exception {
"----------\n":
"----------\n" +
"1. WARNING in Test.java (at line 3)\n" +
- " public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" +
+ " public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" +
" ^^^^\n" +
"The serializable class Test does not declare a static final serialVersionUID field of type long\n" +
"----------\n" +
@@ -13472,7 +13454,7 @@ public void testBug317719h() throws Exception {
"3. ERROR in Test.java (at line 5)\n" +
" public Collection<Value> get(Key k) { return null; }\n" +
" ^^^^^^^^^^\n" +
- "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type LinkedHashMap<K,V> but does not override it\n" +
+ "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type HashMap<K,V> but does not override it\n" +
"----------\n" +
"4. ERROR in Test.java (at line 6)\n" +
" Zork z;\n" +
@@ -13483,8 +13465,8 @@ public void testBug317719h() throws Exception {
new String[] {
"Test.java",
"import java.util.Collection;\n" +
- "import java.util.LinkedHashMap;\n" +
- "public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" +
+ "import java.util.HashMap;\n" +
+ "public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" +
" public Collection<Value> put(Key k, Value v) { return null; }\n" +
" public Collection<Value> get(Key k) { return null; }\n" +
" Zork z;\n" +
@@ -13512,4 +13494,50 @@ public void test345949a() throws Exception {
"Name clash: The method foo(A<Integer>) of type Sub has the same erasure as foo(A<Number>) of type Super but does not hide it\n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355838
+public void testBug355838() throws Exception {
+ String output =
+ "----------\n" +
+ "1. ERROR in ErasureBug.java (at line 4)\n" +
+ " public String output(List<String> integers) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Method output(List<String>) has the same erasure output(List<E>) as another method in type ErasureBug\n" +
+ "----------\n" +
+ "2. ERROR in ErasureBug.java (at line 7)\n" +
+ " public String output(List doubles) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^\n" +
+ "Method output(List) has the same erasure output(List<E>) as another method in type ErasureBug\n" +
+ "----------\n" +
+ "3. WARNING in ErasureBug.java (at line 7)\n" +
+ " public String output(List doubles) {\n" +
+ " ^^^^\n" +
+ "List is a raw type. References to generic type List<E> should be parameterized\n" +
+ "----------\n" +
+ "4. WARNING in ErasureBug.java (at line 10)\n" +
+ " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" +
+ " ^^^^^^^^^^^^^^^\n" +
+ "Type safety: The expression of type ArrayList needs unchecked conversion to conform to List<String>\n" +
+ "----------\n" +
+ "5. WARNING in ErasureBug.java (at line 10)\n" +
+ " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" +
+ " ^^^^^^^^^\n" +
+ "ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized\n" +
+ "----------\n";
+ this.runNegativeTest(
+ new String[] {
+ "ErasureBug.java",
+ "import java.util.ArrayList;\n" +
+ "import java.util.List;\n" +
+ "public class ErasureBug {\n" +
+ " public String output(List<String> integers) {\n" +
+ " return \"1\";\n" +
+ " }\n" +
+ " public String output(List doubles) {\n" +
+ " return \"2\";\n" +
+ " }\n" +
+ " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" +
+ "}\n"
+ },
+ output);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index f3355b450..1ac26d01f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -18,6 +18,9 @@
* bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
* bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
* bug 354554 - [null] conditional with redundant condition yields weak error message
+ * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
+ * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -45,7 +48,7 @@ public NullReferenceTest(String name) {
// Only the highest compliance level is run; add the VM argument
// -Dcompliance=1.4 (for example) to lower it if needed
static {
-// TESTS_NAMES = new String[] { "testBug348379" };
+// TESTS_NAMES = new String[] { "testBug360328" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -6031,12 +6034,17 @@ public void test0562_try_catch_unchecked_exception() {
" }\n" +
" }\n" +
"}\n"},
- "----------\n" +
- "1. ERROR in X.java (at line 8)\n" +
- " o.toString();\n" +
- " ^\n" +
- "Potential null pointer access: The variable o may be null at this location\n" +
- "----------\n",
+ "----------\n" +
+ "1. WARNING in X.java (at line 6)\n" +
+ " o = new LineNumberReader(new FileReader(\"dummy\"));\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'o' is never closed\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " o.toString();\n" +
+ " ^\n" +
+ "Potential null pointer access: The variable o may be null at this location\n" +
+ "----------\n",
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
}
@@ -14946,4 +14954,448 @@ public void testBug354554b() {
"Redundant null check: The variable u cannot be null at this location\n" +
"----------\n");
}
+// Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
+public void test358827() {
+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) {
+ this.runNegativeTest(
+ new String[] {
+ "Bug358827.java",
+ "import java.io.FileReader;\n" +
+ "public class Bug358827 {\n" +
+ " Object foo2() throws Exception {\n" +
+ " String o = null;\n" +
+ " try (FileReader rf = new FileReader(\"file\")){\n" +
+ " o = o.toUpperCase();\n" +
+ " } finally {\n" +
+ " o = \"OK\";\n" +
+ " }\n" +
+ " return o;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Bug358827.java (at line 6)\n" +
+ " o = o.toUpperCase();\n" +
+ " ^\n" +
+ "Null pointer access: The variable o can only be null at this location\n" +
+ "----------\n");
+ }
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
+public void testBug256796() {
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE);
+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.DISABLED);
+ this.runNegativeTest(
+ new String[] {
+ "Bug.java",
+ "public class Bug {\n" +
+ " private static final boolean TRUE = true;\n" +
+ " private static final boolean FALSE = false;\n" +
+ " void foo() throws Exception {\n" +
+ " if (TRUE) return;\n" +
+ " else System.out.println(\"\");\n" +
+ " System.out.println(\"\");\n" + // not dead code
+ " if (TRUE) throw new Exception();\n" +
+ " else System.out.println(\"\");\n" +
+ " System.out.println(\"\");\n" + // not dead code
+ " if (TRUE) return;\n" +
+ " System.out.println(\"\");\n" + // not dead code
+ " if (FALSE) System.out.println(\"\");\n" +
+ " else return;\n" +
+ " System.out.println(\"\");\n" + // not dead code
+ " if (FALSE) return;\n" +
+ " System.out.println(\"\");\n" + // not dead code
+ " if (false) return;\n" + // dead code
+ " System.out.println(\"\");\n" +
+ " if (true) return;\n" +
+ " System.out.println(\"\");\n" + // dead code
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in Bug.java (at line 18)\n" +
+ " if (false) return;\n" +
+ " ^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "2. WARNING in Bug.java (at line 21)\n" +
+ " System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n",
+ null,
+ true,
+ compilerOptions);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
+public void testBug256796a() {
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE);
+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.ENABLED);
+ this.runNegativeTest(
+ new String[] {
+ "Bug.java",
+ "public class Bug {\n" +
+ " private static final boolean TRUE = true;\n" +
+ " private static final boolean FALSE = false;\n" +
+ " void foo() throws Exception {\n" +
+ " if (TRUE) return;\n" +
+ " else System.out.println(\"\");\n" +
+ " System.out.println(\"\");\n" + // dead code
+ " }\n" +
+ " void foo2() {\n" +
+ " if (TRUE) return;\n" +
+ " System.out.println(\"\");\n" + // dead code
+ " }\n" +
+ " void foo3() throws Exception {\n" +
+ " if (TRUE) throw new Exception();\n" +
+ " else System.out.println(\"\");\n" + // dead code
+ " System.out.println(\"\");\n" + // dead code
+ " }\n" +
+ " void foo4() throws Exception {\n" +
+ " if (FALSE) System.out.println(\"\");\n" +
+ " else return;\n" +
+ " System.out.println(\"\");\n" + // dead code
+ " }\n" +
+ " void foo5() throws Exception {\n" +
+ " if (FALSE) return;\n" + // dead code
+ " System.out.println(\"\");\n" +
+ " }\n" +
+ " void foo6() throws Exception {\n" +
+ " if (false) return;\n" + // dead code
+ " System.out.println(\"\");\n" +
+ " if (true) return;\n" +
+ " System.out.println(\"\");\n" + // dead code
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in Bug.java (at line 6)\n" +
+ " else System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "2. WARNING in Bug.java (at line 7)\n" +
+ " System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "3. WARNING in Bug.java (at line 11)\n" +
+ " System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "4. WARNING in Bug.java (at line 15)\n" +
+ " else System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "5. WARNING in Bug.java (at line 16)\n" +
+ " System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "6. WARNING in Bug.java (at line 19)\n" +
+ " if (FALSE) System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "7. WARNING in Bug.java (at line 21)\n" +
+ " System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "8. WARNING in Bug.java (at line 24)\n" +
+ " if (FALSE) return;\n" +
+ " ^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "9. WARNING in Bug.java (at line 28)\n" +
+ " if (false) return;\n" +
+ " ^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "10. WARNING in Bug.java (at line 31)\n" +
+ " System.out.println(\"\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n",
+ null,
+ true,
+ compilerOptions);
+}
+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+public void testBug360328() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
+ runNegativeTest(
+ true, /* flushOutputDir */
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void print4() {\n" +
+ " final String s1 = \"\";\n" +
+ " for (int i=0; i<4; i++)\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " if (s1 != null)\n" +
+ " s1.toString();\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ " void print16(boolean b) {\n" +
+ " final String s3 = b ? null : \"\";\n" +
+ " for (int i=0; i<16; i++)\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " s3.toString();\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ " void print23() {\n" +
+ " final String s23 = null;\n" +
+ " for (int i=0; i<23; i++)\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " s23.toString();\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ "}\n",
+
+ },
+ null, /* classLibs */
+ customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " if (s1 != null)\n" +
+ " ^^\n" +
+ "Redundant null check: The variable s1 cannot be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 17)\n" +
+ " s3.toString();\n" +
+ " ^^\n" +
+ "Potential null pointer access: The variable s3 may be null at this location\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 26)\n" +
+ " s23.toString();\n" +
+ " ^^^\n" +
+ "Null pointer access: The variable s23 can only be null at this location\n" +
+ "----------\n",
+ "",/* expected output */
+ "",/* expected error */
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+// constructors
+public void testBug360328b() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
+ runNegativeTest(
+ true, /* flushOutputDir */
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void print4() {\n" +
+ " final String s1 = \"\";\n" +
+ " for (int i=0; i<4; i++) {\n" +
+ " class R {\n" +
+ " public R() {\n" +
+ " if (s1 != null)\n" +
+ " s1.toString();\n" +
+ " }\n" +
+ " };\n" +
+ " new R();\n" +
+ " }\n" +
+ " }\n" +
+ " void print16(boolean b) {\n" +
+ " final String s3 = b ? null : \"\";\n" +
+ " int i=0; while (i++<16) {\n" +
+ " class R {\n" +
+ " public R() {\n" +
+ " s3.toString();\n" +
+ " }\n" +
+ " };\n" +
+ " new R();\n" +
+ " };\n" +
+ " }\n" +
+ " void print23() {\n" +
+ " final String s23 = null;\n" +
+ " for (int i=0; i<23; i++) {\n" +
+ " class R {\n" +
+ " public R() {\n" +
+ " s23.toString();\n" +
+ " }\n" +
+ " };\n" +
+ " new R();\n" +
+ " };\n" +
+ " }\n" +
+ "}\n",
+
+ },
+ null, /* classLibs */
+ customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " if (s1 != null)\n" +
+ " ^^\n" +
+ "Redundant null check: The variable s1 cannot be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 19)\n" +
+ " s3.toString();\n" +
+ " ^^\n" +
+ "Potential null pointer access: The variable s3 may be null at this location\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 30)\n" +
+ " s23.toString();\n" +
+ " ^^^\n" +
+ "Null pointer access: The variable s23 can only be null at this location\n" +
+ "----------\n",
+ "",/* expected output */
+ "",/* expected error */
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+// initializers
+public void testBug360328c() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE);
+ runNegativeTest(
+ true, /* flushOutputDir */
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void print4() {\n" +
+ " final String s1 = \"\";\n" +
+ " for (int i=0; i<4; i++) {\n" +
+ " class R {\n" +
+ " String s1R;\n" +
+ " {\n" +
+ " if (s1 != null)\n" +
+ " s1R = s1;\n" +
+ " }\n" +
+ " };\n" +
+ " new R();\n" +
+ " }\n" +
+ " }\n" +
+ " void print16(boolean b) {\n" +
+ " final String s3 = b ? null : \"\";\n" +
+ " for (int i=0; i<16; i++) {\n" +
+ " class R {\n" +
+ " String s3R = s3.toString();\n" +
+ " };\n" +
+ " new R();\n" +
+ " };\n" +
+ " }\n" +
+ " void print23() {\n" +
+ " final String s23 = null;\n" +
+ " for (int i=0; i<23; i++) {\n" +
+ " class R {\n" +
+ " String s23R;\n" +
+ " {\n" +
+ " s23R = s23.toString();\n" +
+ " }\n" +
+ " };\n" +
+ " new R();\n" +
+ " };\n" +
+ " }\n" +
+ "}\n",
+
+ },
+ null, /* classLibs */
+ customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " if (s1 != null)\n" +
+ " ^^\n" +
+ "Redundant null check: The variable s1 cannot be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 19)\n" +
+ " String s3R = s3.toString();\n" +
+ " ^^\n" +
+ "Potential null pointer access: The variable s3 may be null at this location\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 30)\n" +
+ " s23R = s23.toString();\n" +
+ " ^^^\n" +
+ "Null pointer access: The variable s23 can only be null at this location\n" +
+ "----------\n",
+ "",/* expected output */
+ "",/* expected error */
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+// try-finally instead of loop
+public void testBug360328d() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
+ runNegativeTest(
+ true, /* flushOutputDir */
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void print4() {\n" +
+ " final String s1 = \"\";\n" +
+ " try { } finally {\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " if (s1 != null)\n" +
+ " s1.toString();\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ " }\n" +
+ " void print16(boolean b) {\n" +
+ " final String s3 = b ? null : \"\";\n" +
+ " try { } finally {\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " s3.toString();\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ " }\n" +
+ " void print23() {\n" +
+ " final String s23 = null;\n" +
+ " try { } finally {\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " s23.toString();\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+
+ },
+ null, /* classLibs */
+ customOptions,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " if (s1 != null)\n" +
+ " ^^\n" +
+ "Redundant null check: The variable s1 cannot be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 18)\n" +
+ " s3.toString();\n" +
+ " ^^\n" +
+ "Potential null pointer access: The variable s3 may be null at this location\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 28)\n" +
+ " s23.toString();\n" +
+ " ^^^\n" +
+ "Null pointer access: The variable s23 can only be null at this location\n" +
+ "----------\n",
+ "",/* expected output */
+ "",/* expected error */
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java
index a551aa001..3b4db3713 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java
@@ -7076,4 +7076,116 @@ public void test124b() {
compilerOptions /* custom options */
);
}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354502
+// Anonymous class instantiation of a non-static member type, method can't be static
+public void test354502() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return;
+ Map compilerOptions = getCompilerOptions();
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR);
+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR);
+ compilerOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public abstract class Abstract{}\n" +
+ " public static abstract class Abstract2{}\n" +
+ " private void method1() {\n" + // don't warn
+ " new Abstract() {};\n" +
+ " }\n" +
+ " private void method2() {\n" + // warn
+ " new Abstract2() {};\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " private void method2() {\n" +
+ " ^^^^^^^^^\n" +
+ "The method method2() from the type X can be declared as static\n" +
+ "----------\n",
+ null /* no extra class libraries */,
+ true /* flush output directory */,
+ compilerOptions /* custom options */
+ );
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164
+public void test360164() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
+ this.runConformTest(
+ new String[] {
+ "p/B.java",
+ "package p;\n" +
+ "\n" +
+ "public abstract class B<K,V> {\n" +
+ " protected abstract V foo(K element);\n" +
+ "}\n",
+ "p/C.java",
+ "package p;\n" +
+ "public class C {\n" +
+ "}\n",
+ "p/D.java",
+ "package p;\n" +
+ "public class D extends E {\n" +
+ "}\n",
+ "p/E.java",
+ "package p;\n" +
+ "public abstract class E implements I {\n" +
+ "}\n",
+ "p/I.java",
+ "package p;\n" +
+ "public interface I {\n" +
+ "}\n",
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ " private final class A extends B<C,D>{\n" +
+ " @Override\n" +
+ " protected D foo(C c) {\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+ },
+ "");
+
+ // delete binary file I (i.e. simulate removing it from classpath for subsequent compile)
+ Util.delete(new File(OUTPUT_DIR, "p" + File.separator + "I.class"));
+
+ runNegativeTest(
+ // test directory preparation
+ false /* do not flush output directory */,
+ new String[] { /* test files */
+ "p/X.java",
+ "package p;\n" +
+ "public class X {\n" +
+ " private final class A extends B<C,D>{\n" +
+ " @Override\n" +
+ " protected D foo(C c) {\n" +
+ " Zork z;\n" +
+ " return null;\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+ },
+ // compiler options
+ null /* no class libraries */,
+ null /* no custom options */,
+ // compiler results
+ "----------\n" +
+ "1. WARNING in p\\X.java (at line 3)\n" +
+ " private final class A extends B<C,D>{\n" +
+ " ^\n" +
+ "The type X.A is never used locally\n" +
+ "----------\n" +
+ "2. ERROR in p\\X.java (at line 6)\n" +
+ " Zork z;\n" +
+ " ^^^^\n" +
+ "Zork cannot be resolved to a type\n" +
+ "----------\n",
+ // javac options
+ JavacTestOptions.SKIP_UNTIL_FRAMEWORK_FIX /* javac test options */);
+}
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
index de0e7c619..afc568e8d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
@@ -33,7 +33,7 @@ public class StackMapAttributeTest extends AbstractRegressionTest {
// All specified tests which does not belong to the class are skipped...
static {
// TESTS_PREFIX = "testBug95521";
-// TESTS_NAMES = new String[] { "testBug83127a" };
+// TESTS_NAMES = new String[] { "testBug359495" };
// TESTS_NUMBERS = new int[] { 53 };
// TESTS_RANGE = new int[] { 23 -1,};
}
@@ -6802,4 +6802,207 @@ public class StackMapAttributeTest extends AbstractRegressionTest {
},
"SUCCESS");
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495
+ public void testBug359495a() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "import java.util.concurrent.locks.Lock;\n" +
+ "import java.util.Arrays;\n" +
+ "import java.util.concurrent.locks.ReentrantLock;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " final Lock lock = new ReentrantLock();\n" +
+ " final List<String> strings = Arrays.asList(args);\n" +
+ " lock.lock();\n" +
+ " try{\n" +
+ " for (final String string:strings){\n" +
+ " return;\n" +
+ " }\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " lock.unlock();\n" +
+ " }" +
+ " }\n" +
+ "}",
+ },
+ "");
+
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class"));
+ String actualOutput =
+ disassembler.disassemble(
+ classFileBytes,
+ "\n",
+ ClassFileBytesDisassembler.DETAILED);
+
+ String expectedOutput =
+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
+ " // Stack: 2, Locals: 6\n" +
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" +
+ " 3 dup\n" +
+ " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" +
+ " 7 astore_1 [lock]\n" +
+ " 8 aload_0 [args]\n" +
+ " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" +
+ " 12 astore_2 [strings]\n" +
+ " 13 aload_1 [lock]\n" +
+ " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" +
+ " 19 aload_2 [strings]\n" +
+ " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" +
+ " 25 astore 4\n" +
+ " 27 aload 4\n" +
+ " 29 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" +
+ " 34 ifeq 55\n" +
+ " 37 aload 4\n" +
+ " 39 invokeinterface java.util.Iterator.next() : java.lang.Object [42] [nargs: 1]\n" +
+ " 44 checkcast java.lang.String [46]\n" +
+ " 47 astore_3 [string]\n" +
+ " 48 aload_1 [lock]\n" +
+ " 49 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" +
+ " 54 return\n" +
+ " 55 aload_1 [lock]\n" +
+ " 56 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" +
+ " 61 return\n" +
+ " 62 astore 5\n" +
+ " 64 aload_1 [lock]\n" +
+ " 65 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" +
+ " 70 aload 5\n" +
+ " 72 athrow\n" +
+ " Exception Table:\n" +
+ " [pc: 19, pc: 48] -> 62 when : any\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 7]\n" +
+ " [pc: 8, line: 8]\n" +
+ " [pc: 13, line: 9]\n" +
+ " [pc: 19, line: 11]\n" +
+ " [pc: 48, line: 16]\n" +
+ " [pc: 54, line: 12]\n" +
+ " [pc: 55, line: 16]\n" +
+ " [pc: 61, line: 14]\n" +
+ " [pc: 62, line: 15]\n" +
+ " [pc: 64, line: 16]\n" +
+ " [pc: 70, line: 17]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 73] local: args index: 0 type: java.lang.String[]\n" +
+ " [pc: 8, pc: 73] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" +
+ " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List\n" +
+ " [pc: 48, pc: 55] local: string index: 3 type: java.lang.String\n" +
+ " Local variable type table:\n" +
+ " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List<java.lang.String>\n" +
+ " Stack map table: number of frames 2\n" +
+ " [pc: 55, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" +
+ " [pc: 62, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" ;
+
+ int index = actualOutput.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(actualOutput, 2));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, actualOutput);
+ }
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495
+ public void testBug359495b() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "import java.util.Iterator;\n" +
+ "import java.util.concurrent.locks.Lock;\n" +
+ "import java.util.Arrays;\n" +
+ "import java.util.concurrent.locks.ReentrantLock;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " final Lock lock = new ReentrantLock();\n" +
+ " final List<String> strings = Arrays.asList(args);\n" +
+ " lock.lock();\n" +
+ " try{\n" +
+ " for (Iterator i = strings.iterator(); i.hasNext();){\n" +
+ " return;\n" +
+ " }\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " lock.unlock();\n" +
+ " }" +
+ " }\n" +
+ "}",
+ },
+ "");
+
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class"));
+ String actualOutput =
+ disassembler.disassemble(
+ classFileBytes,
+ "\n",
+ ClassFileBytesDisassembler.DETAILED);
+
+ String expectedOutput =
+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" +
+ " // Stack: 2, Locals: 5\n" +
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" +
+ " 3 dup\n" +
+ " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" +
+ " 7 astore_1 [lock]\n" +
+ " 8 aload_0 [args]\n" +
+ " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" +
+ " 12 astore_2 [strings]\n" +
+ " 13 aload_1 [lock]\n" +
+ " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" +
+ " 19 aload_2 [strings]\n" +
+ " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" +
+ " 25 astore_3 [i]\n" +
+ " 26 aload_3 [i]\n" +
+ " 27 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" +
+ " 32 ifeq 42\n" +
+ " 35 aload_1 [lock]\n" +
+ " 36 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" +
+ " 41 return\n" +
+ " 42 aload_1 [lock]\n" +
+ " 43 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" +
+ " 48 return\n" +
+ " 49 astore 4\n" +
+ " 51 aload_1 [lock]\n" +
+ " 52 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" +
+ " 57 aload 4\n" +
+ " 59 athrow\n" +
+ " Exception Table:\n" +
+ " [pc: 19, pc: 35] -> 49 when : any\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 8]\n" +
+ " [pc: 8, line: 9]\n" +
+ " [pc: 13, line: 10]\n" +
+ " [pc: 19, line: 12]\n" +
+ " [pc: 35, line: 17]\n" +
+ " [pc: 41, line: 13]\n" +
+ " [pc: 42, line: 17]\n" +
+ " [pc: 48, line: 15]\n" +
+ " [pc: 49, line: 16]\n" +
+ " [pc: 51, line: 17]\n" +
+ " [pc: 57, line: 18]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 60] local: args index: 0 type: java.lang.String[]\n" +
+ " [pc: 8, pc: 60] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" +
+ " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List\n" +
+ " [pc: 26, pc: 42] local: i index: 3 type: java.util.Iterator\n" +
+ " Local variable type table:\n" +
+ " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List<java.lang.String>\n" +
+ " Stack map table: number of frames 2\n" +
+ " [pc: 42, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" +
+ " [pc: 49, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n";
+
+ int index = actualOutput.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(actualOutput, 2));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, actualOutput);
+ }
+ }
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
index bae6a3c01..78f8badf0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java
@@ -2484,10 +2484,10 @@ public class StaticImportTest extends AbstractComparableTest {
"}\n",
},
"----------\n" +
- "1. ERROR in p1\\A.java (at line 7)\n" +
- " int v2 = b.fooC;\n" +
+ "1. ERROR in p1\\A.java (at line 6)\n" +
+ " int v1 = b.fooB;\n" +
" ^^^^\n" +
- "fooC cannot be resolved or is not a field\n" +
+ "fooB cannot be resolved or is not a field\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=256375
@@ -2720,5 +2720,175 @@ public class StaticImportTest extends AbstractComparableTest {
"----------\n"
);
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401
+ public void test081() {
+ this.runConformTest(
+ new String[] {
+ "Test.java",
+ "import static p1.Bar.B;\n" +
+ "import p3.Foo.*;\n" +
+ "public class Test {\n" +
+ " public static void main(String [] args){\n" +
+ " new Test().beginTest();" +
+ " }\n" +
+ " public void beginTest(){\n" +
+ " System.out.print(\"1 + 1 = \");\n" +
+ " if(alwaysTrue()) System.out.println(\"2\");\n" +
+ " else System.out.println(\"3\"); " +
+ " }\n" +
+ " public boolean alwaysTrue(){\n" +
+ " String myB = B.class.getCanonicalName();;\n" + // refers to p1.Bar.B (class)
+ " String realB = p1.Bar.B.class.getCanonicalName();;\n" + // refers to p1.Bar.B (class)
+ " B();\n" + // refers to p1.Bar.B() (method)
+ " return myB.equals(realB);\n" +
+ " }\n" +
+ "}\n",
+ "p1/Bar.java",
+ "package p1;\n" +
+ "public class Bar{\n" +
+ " public static class B{}\n" +
+ " final public static String B = new String(\"random\");\n" +
+ " public static void B(){}\n" +
+ "}\n",
+ "p3/Foo.java",
+ "package p3;\n" +
+ "public class Foo {\n" +
+ " public class B{\n" +
+ " public int a;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "1 + 1 = 2");
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401
+ public void test082() {
+ this.runNegativeTest(
+ new String[] {
+ "p1/Bar.java",
+ "package p1;\n" +
+ "public class Bar{\n" +
+ " public static class B{}\n" +
+ " final public static String B = new String(\"random\");\n" +
+ " public static void B(){}\n" +
+ "}\n",
+ "p3/Foo.java",
+ "package p3;\n" +
+ "public class Foo {\n" +
+ " public class B{\n" +
+ " public int a;\n" +
+ " }\n" +
+ "}\n",
+ "p2/Test.java",
+ "package p2;\n" +
+ "import static p1.Bar.B;\n" +
+ "import p3.Foo.*;\n" +
+ "public class Test {\n" +
+ " public static void main(String [] args){\n" +
+ " new Test().beginTest();" +
+ " }\n" +
+ " public void beginTest(){\n" +
+ " System.out.print(\"1 + 1 = \");\n" +
+ " if(alwaysTrue()) System.out.println(\"2\");\n" +
+ " else System.out.println(\"3\"); " +
+ " }\n" +
+ " public boolean alwaysTrue(){\n" +
+ " B b = null;\n" + // refers to p1.Bar.B (class)
+ " String realB = B;\n" + // refers to p1.Bar.B (field)
+ " B();\n" + // refers to p1.Bar.B() (method)
+ " int abc = b.a;\n;" + // static import for Bar.B overshadows on demand import Foo.B
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in p2\\Test.java (at line 15)\n" +
+ " int abc = b.a;\n" +
+ " ^\n" +
+ "a cannot be resolved or is not a field\n" +
+ "----------\n");
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401
+ public void test083() {
+ this.runConformTest(
+ new String[] {
+ "Test.java",
+ "import static p1.Bar.B;\n" +
+ "import p3.Foo.*;\n" +
+ "public class Test {\n" +
+ " public static void main(String [] args){\n" +
+ " new Test().test2();" +
+ " }\n" +
+ " public void test2(){\n" +
+ " System.out.println(B.toString());\n" + // Field obscures class B
+ " System.out.println(p1.Bar.B.toString());\n" + // Field obscures the class B
+ " System.out.println(B.class.getCanonicalName().toString());\n" + // the class B
+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + // class B
+ " }\n" +
+ "}\n",
+ "p1/Bar.java",
+ "package p1;\n" +
+ "public class Bar{\n" +
+ " public static class B{}\n" +
+ " final public static String B = new String(\"random\");\n" +
+ " public static void B(){}\n" +
+ "}\n",
+ "p3/Foo.java",
+ "package p3;\n" +
+ "public class Foo {\n" +
+ " public class B{\n" +
+ " public int a;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "random\n" +
+ "random\n" +
+ "p1.Bar.B\n" +
+ "p1.Bar.B");
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401
+ // Check if we're able to find the correct static member type being imported,
+ // even though the import originally resolved to the static field of the same name,
+ // coming from the supertype
+ public void test084() {
+ this.runConformTest(
+ new String[] {
+ "Test.java",
+ "import static p1.Bar.B;\n" +
+ "import p3.Foo.*;\n" +
+ "public class Test {\n" +
+ " public static void main(String [] args){\n" +
+ " new Test().test2();" +
+ " }\n" +
+ " public void test2(){\n" +
+ " System.out.println(B.class.getCanonicalName().toString());\n" + // the class B
+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + // class B
+ " }\n" +
+ "}\n",
+ "p1/Bar.java",
+ "package p1;\n" +
+ "public class Bar extends SuperBar{\n" +
+ " public static class B{}\n" +
+ " public static void B(){}\n" +
+ "}\n",
+ "p1/SuperBar.java",
+ "package p1;\n" +
+ "public class SuperBar {\n" +
+ " final public static String B = new String(\"random\");\n" +
+ "}\n",
+ "p3/Foo.java",
+ "package p3;\n" +
+ "public class Foo {\n" +
+ " public class B{\n" +
+ " public int a;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "p1.Bar.B\n" +
+ "p1.Bar.B");
+ }
+
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
index 78b5aa403..49dced161 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
@@ -758,7 +758,7 @@ public void test023() {
"1. ERROR in X.java (at line 6)\n" +
" } catch(AX e) {\n" +
" ^^\n" +
- "Unreachable catch block for AX. Only more specific exceptions are thrown and handled by previous catch block(s).\n" +
+ "Unreachable catch block for AX. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" +
"----------\n" +
"2. WARNING in X.java (at line 10)\n" +
" class AX extends Exception {}\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java
index e178b043c..530f636ba 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java
@@ -7,18 +7,23 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contributions for
+ * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
+ * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import java.util.Map;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import junit.framework.Test;
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "test055", "test055a" };
+// TESTS_NAMES = new String[] { "test056throw"};
// TESTS_NUMBERS = new int[] { 50 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -485,12 +490,17 @@ public void test014() {
" ^^\n" +
"Dead code\n" +
"----------\n" +
- "3. ERROR in X.java (at line 5)\n" +
+ "3. WARNING in X.java (at line 5)\n" +
+ " Y why = new Y();\n" +
+ " ^^^\n" +
+ "Resource leak: 'why' is never closed\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 5)\n" +
" Y why = new Y();\n" +
" ^^^^^^^\n" +
"Unhandled exception type WeirdException\n" +
"----------\n" +
- "4. WARNING in X.java (at line 22)\n" +
+ "5. WARNING in X.java (at line 22)\n" +
" class WeirdException extends Throwable {}\n" +
" ^^^^^^^^^^^^^^\n" +
"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" +
@@ -558,12 +568,17 @@ public void test016() {
" ^^\n" +
"Dead code\n" +
"----------\n" +
- "3. ERROR in X.java (at line 5)\n" +
+ "3. WARNING in X.java (at line 5)\n" +
+ " Y why = new Y();\n" +
+ " ^^^\n" +
+ "Resource leak: 'why' is never closed\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 5)\n" +
" Y why = new Y();\n" +
" ^^^^^^^\n" +
"Unhandled exception type WeirdException\n" +
"----------\n" +
- "4. WARNING in X.java (at line 20)\n" +
+ "5. WARNING in X.java (at line 20)\n" +
" class WeirdException extends Throwable {}\n" +
" ^^^^^^^^^^^^^^\n" +
"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" +
@@ -3297,6 +3312,57 @@ public void test053() {
"Unhandled exception type IOException\n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348705
+// Variant of the above, witness for https://bugs.eclipse.org/358827#c6
+public void test053a() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void method1(){\n" +
+ " try (Y y = new Y()) { \n" +
+ " y.close();\n" +
+ " System.out.println();\n" +
+ " } catch (RuntimeException e) {\n" +
+ " } finally {\n" +
+ " System.out.println();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n" +
+ "class Y implements Managed {\n" +
+ " public Y() throws CloneNotSupportedException {}\n" +
+ " public void close () throws ClassNotFoundException, java.io.IOException {\n" +
+ " }\n" +
+ "}\n" +
+ "interface Managed extends AutoCloseable {}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " try (Y y = new Y()) { \n" +
+ " ^\n" +
+ "Unhandled exception type ClassNotFoundException thrown by automatic close() invocation on y\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 3)\n" +
+ " try (Y y = new Y()) { \n" +
+ " ^\n" +
+ "Unhandled exception type IOException thrown by automatic close() invocation on y\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 3)\n" +
+ " try (Y y = new Y()) { \n" +
+ " ^^^^^^^\n" +
+ "Unhandled exception type CloneNotSupportedException\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 4)\n" +
+ " y.close();\n" +
+ " ^^^^^^^^^\n" +
+ "Unhandled exception type ClassNotFoundException\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 4)\n" +
+ " y.close();\n" +
+ " ^^^^^^^^^\n" +
+ "Unhandled exception type IOException\n" +
+ "----------\n");
+}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862 (NPE when union type is used in the resource section.)
public void test054() {
this.runNegativeTest(
@@ -3380,6 +3446,1736 @@ public void test055a() {
},
"Done");
}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable without ever closing it.
+public void test056() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler
+// " char[] in = new char[50];\n" +
+// " fileReader.read(in);\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is never closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable and closes it but not protected by t-w-r nor regular try-finally
+public void test056a() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " try {\n" +
+ " new X().foo();\n" +
+ " } catch (IOException ioex) {\n" +
+ " System.out.println(\"caught\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource 'fileReader' should be managed by try-with-resource\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable and closes it properly in a finally block
+public void test056b() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " try {\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " } finally {\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " try {\n" +
+ " new X().foo();\n" +
+ " } catch (IOException ioex) {\n" +
+ " System.out.println(\"caught\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "caught", /*output*/
+ null/*classLibs*/,
+ true/*shouldFlush*/,
+ null/*vmargs*/,
+ options,
+ null/*requestor*/);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable properly within try-with-resources.
+public void test056c() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " try (FileReader fileReader = new FileReader(file)) {\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " try {\n" +
+ " new X().foo();\n" +
+ " } catch (IOException ioex) {\n" +
+ " System.out.println(\"caught\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "caught", /*output*/
+ null/*classLibs*/,
+ true/*shouldFlush*/,
+ null/*vmargs*/,
+ options,
+ null/*requestor*/);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses two AutoCloseables (testing independent analysis)
+// - one closeable may be unclosed at a conditional return
+// - the other is only conditionally closed
+public void test056d() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo(boolean flag1, boolean flag2) throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " char[] in = new char[50];\n" +
+ " FileReader fileReader1 = new FileReader(file);\n" +
+ " fileReader1.read(in);\n" +
+ " FileReader fileReader2 = new FileReader(file);\n" +
+ " fileReader2.read(in);\n" +
+ " if (flag1) {\n" +
+ " fileReader2.close();\n" +
+ " return;\n" +
+ " } else if (flag2) {\n" +
+ " fileReader2.close();\n" +
+ " }\n" +
+ " fileReader1.close();\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo(false, true);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 10)\n" +
+ " FileReader fileReader2 = new FileReader(file);\n" +
+ " ^^^^^^^^^^^\n" +
+ "Potential resource leak: 'fileReader2' may not be closed\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 14)\n" +
+ " return;\n" +
+ " ^^^^^^^\n" +
+ "Resource leak: 'fileReader1' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+//Bug 349326 - [1.7] new warning for missing try-with-resources
+//a method uses two AutoCloseables (testing independent analysis)
+//- one closeable may be unclosed at a conditional return
+//- the other is only conditionally closed
+public void test056d_suppress() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo(boolean flag1, boolean flag2) throws IOException {\n" +
+ " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" +
+ " char[] in = new char[50];\n" +
+ " FileReader fileReader1 = new FileReader(file);\n" +
+ " fileReader1.read(in);\n" +
+ " @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" +
+ " fileReader2.read(in);\n" +
+ " if (flag1) {\n" +
+ " fileReader2.close();\n" +
+ " return; // not suppressed\n" +
+ " } else if (flag2) {\n" +
+ " fileReader2.close();\n" +
+ " }\n" +
+ " fileReader1.close();\n" +
+ " }\n" +
+ " @SuppressWarnings(\"resource\") // useful suppress\n" +
+ " void bar() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo(false, true);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 6)\n" +
+ " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" +
+ " ^^^^^^^^^^\n" +
+ "Unnecessary @SuppressWarnings(\"resource\")\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 14)\n" +
+ " return; // not suppressed\n" +
+ " ^^^^^^^\n" +
+ "Resource leak: 'fileReader1' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// one method returns an AutoCleasble, a second method uses this object without ever closing it.
+public void test056e() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " FileReader getReader(String filename) throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " return fileReader;\n" + // don't complain here, pass responsibility to caller
+ " }\n" +
+ " void foo() throws IOException {\n" +
+ " FileReader reader = getReader(\"somefile\");\n" +
+ " char[] in = new char[50];\n" +
+ " reader.read(in);\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " FileReader reader = getReader(\"somefile\");\n" +
+ " ^^^^^^\n" +
+ "Resource leak: 'reader' is never closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method explicitly closes its AutoCloseable rather than using t-w-r
+public void test056f() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = null;\n" +
+ " try {\n" +
+ " fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " } finally {\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " FileReader fileReader = null;\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource 'fileReader' should be managed by try-with-resource\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// an AutoCloseable local is re-assigned
+public void test056g() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " fileReader = new FileReader(file);\n" +
+ " fileReader.read(in);\n" +
+ " fileReader.close();\n" +
+ " fileReader = null;\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 10)\n" +
+ " fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// an AutoCloseable local is re-assigned after null-assigned
+public void test056g2() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " fileReader = null;\n" +
+ " fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here
+ " fileReader.read(in);\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 10)\n" +
+ " fileReader = null;\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// two AutoCloseables at different nesting levels (anonymous local type)
+public void test056h() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " final File file = new File(\"somefile\");\n" +
+ " final FileReader fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " new Runnable() {\n public void run() {\n" +
+ " try {\n" +
+ " fileReader.close();\n" +
+ " FileReader localReader = new FileReader(file);\n" +
+ " } catch (IOException ex) { /* nop */ }\n" +
+ " }}.run();\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 7)\n" +
+ " final FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Potential resource leak: 'fileReader' may not be closed\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 14)\n" +
+ " FileReader localReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^^\n" +
+ "Resource leak: 'localReader' is never closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// three AutoCloseables in different blocks of the same method
+public void test056i() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo(boolean f1, boolean f2) throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " if (f1) {\n" +
+ " FileReader fileReader = new FileReader(file); // err: not closed\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " while (true) {\n" +
+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
+ " loopReader.close();" +
+ " break;\n" +
+ " }\n" +
+ " } else {\n" +
+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
+ " if (f2)\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo(true, true);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " FileReader fileReader = new FileReader(file); // err: not closed\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is never closed\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 16)\n" +
+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
+ " ^^^^^^^^^^\n" +
+ "Potential resource leak: 'fileReader' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// three AutoCloseables in different blocks of the same method
+public void test056i2() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo(boolean f1, boolean f2) throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " if (f1) {\n" +
+ " FileReader fileReader = new FileReader(file); // properly closed\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " while (true) {\n" +
+ " fileReader.close();\n" +
+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
+ " loopReader.close();\n" +
+ " break;\n" +
+ " }\n" +
+ " } else {\n" +
+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
+ " if (f2)\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo(true, true);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 18)\n" +
+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
+ " ^^^^^^^^^^\n" +
+ "Potential resource leak: 'fileReader' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable without closing it locally but passing as arg to another method
+public void test056j() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " read(fileReader);\n" +
+ " }\n" +
+ " void read(FileReader reader) { }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Potential resource leak: 'fileReader' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable without closing it locally but passing as arg to another method
+public void test056jconditional() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo(boolean b) throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " synchronized (b ? this : new X()) {\n" +
+ " new ReadDelegator(fileReader);\n" +
+ " }\n" +
+ " }\n" +
+ " class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo(true);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Potential resource leak: 'fileReader' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// many locals, some are AutoCloseable.
+// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3,
+// doing so would create false positives.
+public void test056k() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" +
+ " i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" +
+ " i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" +
+ " i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" +
+ " i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader ra1 = null, ra2 = null;\n" +
+ " try {\n" +
+ " ra1 = new FileReader(file);\n" +
+ " ra2 = new FileReader(file);\n" +
+ " FileReader ra3 = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " ra1.read(in);\n" +
+ " ra2.read(in);\n" +
+ " ra3.close();\n" +
+ " } finally {\n" +
+ " ra1.close();\n" +
+ " }\n" +
+ " int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits
+ " FileReader rb1 = null, rb2 = null;\n" +
+ " try {\n" +
+ " rb1 = new FileReader(file);\n" +
+ " rb2 = new FileReader(file);\n" +
+ " FileReader rb3 = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " rb1.read(in);\n" +
+ " rb2.read(in);\n" +
+ " rb3.close();\n" +
+ " } finally {\n" +
+ " rb1.close();\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 12)\n" +
+ " FileReader ra1 = null, ra2 = null;\n" +
+ " ^^^\n" +
+ "Resource 'ra1' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 15)\n" +
+ " ra2 = new FileReader(file);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'ra2' is never closed\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 16)\n" +
+ " FileReader ra3 = new FileReader(file);\n" +
+ " ^^^\n" +
+ "Resource 'ra3' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 25)\n" +
+ " FileReader rb1 = null, rb2 = null;\n" +
+ " ^^^\n" +
+ "Resource 'rb1' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 28)\n" +
+ " rb2 = new FileReader(file);\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'rb2' is never closed\n" +
+ "----------\n" +
+ "6. ERROR in X.java (at line 29)\n" +
+ " FileReader rb3 = new FileReader(file);\n" +
+ " ^^^\n" +
+ "Resource 'rb3' should be managed by try-with-resource\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// various non-problems
+public void test056l() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " X(FileReader r0) {}\n" + // don't complain against argument
+ " FileReader getReader() { return null; }\n" +
+ " void foo(FileReader r1) throws IOException {\n" +
+ " FileReader fileReader = getReader();\n" +
+ " if (fileReader == null)\n" +
+ " return;\n" + // don't complain, resource is actually null
+ " FileReader r3 = getReader();\n" +
+ " if (r3 == null)\n" +
+ " r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null
+ " try {\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " r1.read(in);\n" +
+ " } finally {\n" +
+ " fileReader.close();\n" +
+ " r3.close();\n" + // the effect of this close() call might be spoiled by exception in fileReader.close() above, but we ignore exception exits in the analysis
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" +
+ " new X(r2).foo(new FileReader(new File(\"notthere\")));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " FileReader fileReader = getReader();\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource 'fileReader' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
+ " FileReader r3 = getReader();\n" +
+ " ^^\n" +
+ "Resource 'r3' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 24)\n" +
+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" +
+ " ^^\n" +
+ "Potential resource leak: 'r2' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// nested try with early exit
+public void test056m() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() {\n" +
+ " File file = new File(\"somefile\");" +
+ " try {\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " try {\n" +
+ " char[] in = new char[50];\n" +
+ " if (fileReader.read(in)==0)\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " } catch (IOException e) {\n" +
+ " System.out.println(\"caught\");\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "caught", /*output*/
+ null/*classLibs*/,
+ true/*shouldFlush*/,
+ null/*vmargs*/,
+ options,
+ null/*requestor*/);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// nested try should not interfere with earlier analysis.
+public void test056n() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "import java.io.FileNotFoundException;\n" +
+ "public class X {\n" +
+ " void foo(File someFile, char[] buf) throws IOException {\n" +
+ " FileReader fr1 = new FileReader(someFile);\n" +
+ " try {\n" +
+ " fr1.read(buf);\n" +
+ " } finally {\n" +
+ " fr1.close();\n" +
+ " }\n" +
+ " try {\n" +
+ " FileReader fr3 = new FileReader(someFile);\n" +
+ " try {\n" +
+ " } finally {\n" +
+ " fr3.close();\n" +
+ " }\n" +
+ " } catch (IOException e) {\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " try {\n" +
+ " new X().foo(new File(\"missing\"), new char[100]);\n" +
+ " } catch (FileNotFoundException e) {\n" +
+ " System.out.println(\"caught\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "caught", /*output*/
+ null/*classLibs*/,
+ true/*shouldFlush*/,
+ null/*vmargs*/,
+ options,
+ null/*requestor*/);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// if close is guarded by null check this should still be recognized as definitely closed
+public void test056o() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "import java.io.FileNotFoundException;\n" +
+ "public class X {\n" +
+ " void foo(File someFile, char[] buf) throws IOException {\n" +
+ " FileReader fr1 = null;\n" +
+ " try {\n" +
+ " fr1 = new FileReader(someFile);" +
+ " fr1.read(buf);\n" +
+ " } finally {\n" +
+ " if (fr1 != null)\n" +
+ " try {\n" +
+ " fr1.close();\n" +
+ " } catch (IOException e) { /*do nothing*/ }\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " try {\n" +
+ " new X().foo(new File(\"missing\"), new char[100]);\n" +
+ " } catch (FileNotFoundException e) {\n" +
+ " System.out.println(\"caught\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "caught", /*output*/
+ null/*classLibs*/,
+ true/*shouldFlush*/,
+ null/*vmargs*/,
+ options,
+ null/*requestor*/);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// a method uses an AutoCloseable without ever closing it, type from a type variable
+public void test056p() {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.Reader;\n" +
+ "import java.io.IOException;\n" +
+ "public abstract class X <T extends Reader> {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " T fileReader = newReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " }\n" +
+ " abstract T newReader(File file) throws IOException;\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X<FileReader>() {\n" +
+ " FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" +
+ " }.foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " T fileReader = newReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is never closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// closed in dead code
+public void test056q() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " if (2*2 == 4)\n" +
+ " return;\n" +
+ " fileReader.close();\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " FileReader fileReader = new FileReader(file);\n" +
+ " ^^^^^^^^^^\n" +
+ "Resource leak: 'fileReader' is never closed\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 10)\n" +
+ " if (2*2 == 4)\n" +
+ " ^^^^^^^^\n" +
+ "Comparing identical expressions\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 12)\n" +
+ " fileReader.close();\n" +
+ " ^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// closed in dead code
+public void test056r() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " FileReader fr = new FileReader(file);\n" +
+ " Object b = null;\n" +
+ " fr.close();\n" +
+ " if (b != null) {\n" +
+ " fr = new FileReader(file);\n" +
+ " return;\n" +
+ " } else {\n" +
+ " System.out.print(42);\n" +
+ " }\n" +
+ " return; // Should not complain about fr\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 10)\n" +
+ " if (b != null) {\n" +
+ " fr = new FileReader(file);\n" +
+ " return;\n" +
+ " } else {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 13)\n" +
+ " } else {\n" +
+ " System.out.print(42);\n" +
+ " }\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation
+public void test056s() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.File;\n" +
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo() throws IOException {\n" +
+ " File file = new File(\"somefile\");\n" +
+ " try (FileReader fileReader = new FileReader(file);) {\n" +
+ " char[] in = new char[50];\n" +
+ " fileReader.read(in);\n" +
+ " fileReader = new FileReader(file); // debug here\n" +
+ " fileReader.read(in);\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 10)\n" +
+ " fileReader = new FileReader(file); // debug here\n" +
+ " ^^^^^^^^^^\n" +
+ "The resource fileReader of a try-with-resources statement cannot be assigned\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// resource is closed, dead code follows
+public void test056t() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ " void foo31() throws IOException {\n" +
+ " FileReader reader = new FileReader(\"file\"); //warning\n" +
+ " if (reader != null) {\n" +
+ " reader.close();\n" +
+ " } else {\n" +
+ " // nop\n" +
+ " }\n" +
+ " }\n" +
+ " public static void main(String[] args) throws IOException {\n" +
+ " new X().foo31();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " } else {\n" +
+ " // nop\n" +
+ " }\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// resource is reassigned within t-w-r with different resource
+// was initially broken due to https://bugs.eclipse.org/358827
+public void test056u() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo() throws Exception {\n" +
+ " FileReader reader1 = new FileReader(\"file1\");\n" +
+ " FileReader reader2 = new FileReader(\"file2\");\n" +
+ " reader2 = reader1;// this disconnects reader 2\n" +
+ " try (FileReader reader3 = new FileReader(\"file3\")) {\n" +
+ " int ch;\n" +
+ " while ((ch = reader2.read()) != -1) {\n" +
+ " System.out.println(ch);\n" +
+ " reader1.read();\n" +
+ " }\n" +
+ " reader2 = reader1; // warning 1 regarding original reader1\n" + // this warning was missing
+ " reader2 = reader1; // warning 2 regarding original reader1\n" +
+ " } finally {\n" +
+ " if (reader2 != null) {\n" +
+ " reader2.close();\n" +
+ " } else {\n" +
+ " System.out.println();\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " FileReader reader2 = new FileReader(\"file2\");\n" +
+ " ^^^^^^^\n" +
+ "Resource leak: 'reader2' is never closed\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 13)\n" +
+ " reader2 = reader1; // warning 1 regarding original reader1\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'reader1' is not closed at this location\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 14)\n" +
+ " reader2 = reader1; // warning 2 regarding original reader1\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'reader1' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// scope-related pbs reported in https://bugs.eclipse.org/349326#c70 and https://bugs.eclipse.org/349326#c82
+public void test056v() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " boolean foo1() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " int ch;\n" +
+ " while ((ch = reader.read()) != -1) {\n" +
+ " System.out.println(ch);\n" +
+ " reader.read();\n" +
+ " }\n" +
+ " if (ch > 10) {\n" +
+ " return true;\n" +
+ " }\n" +
+ " return false;\n" + // return while resource from enclosing scope remains unclosed
+ " } finally {\n" +
+ " }\n" +
+ " }\n" +
+ " void foo111() throws Exception {\n" +
+ " FileReader reader111 = new FileReader(\"file2\");\n" +
+ " try {\n" +
+ " int ch;\n" +
+ " while ((ch = reader111.read()) != -1) {\n" +
+ " System.out.println(ch);\n" +
+ " reader111.read();\n" +
+ " }\n" +
+ " return;\n" + // this shouldn't spoil the warning "should be managed with t-w-r"
+ " } finally {\n" +
+ " if (reader111 != null) {\n" +
+ " reader111.close();\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " void foo2() throws Exception {\n" +
+ " FileReader reader2 = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " int ch;\n" +
+ " while ((ch = reader2.read()) != -1) {\n" +
+ " System.out.println(ch);\n" +
+ " reader2.read();\n" +
+ " }\n" +
+ " if (ch > 10) {\n" +
+ " return;\n" + // potential leak
+ " }\n" +
+ " } finally {\n" +
+ " }\n" +
+ " reader2.close();\n" + // due to this close we don't say "never closed"
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " ^^^^^^\n" +
+ "Resource leak: 'reader' is never closed\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 19)\n" +
+ " FileReader reader111 = new FileReader(\"file2\");\n" +
+ " ^^^^^^^^^\n" +
+ "Resource 'reader111' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 42)\n" +
+ " return;\n" +
+ " ^^^^^^^\n" +
+ "Resource leak: 'reader2' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// end of method is dead end, but before we have both a close() and an early return
+public void test056w() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " boolean foo1() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " int ch;\n" +
+ " while ((ch = reader.read()) != -1) {\n" +
+ " System.out.println(ch);\n" +
+ " reader.read();\n" +
+ " }\n" +
+ " if (ch > 10) {\n" +
+ " reader.close();\n" +
+ " return true;\n" +
+ " }\n" +
+ " return false;\n" +
+ " } finally {\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 15)\n" +
+ " return false;\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Resource leak: 'reader' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// different early exits, if no close seen report as definitely unclosed
+public void test056x() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo31(boolean b) throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " if (b) {\n" +
+ " reader.close();\n" +
+ " } else {\n" +
+ " return; // warning\n" +
+ " }\n" +
+ " }\n" +
+ " void foo32(boolean b) throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\"); // warn here\n" +
+ " return;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " return; // warning\n" +
+ " ^^^^^^^\n" +
+ "Resource leak: 'reader' is not closed at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 12)\n" +
+ " FileReader reader = new FileReader(\"file\"); // warn here\n" +
+ " ^^^^^^\n" +
+ "Resource leak: 'reader' is never closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// nested method passes the resource to outside code
+public void test056y() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo31(boolean b) throws Exception {\n" +
+ " final FileReader reader31 = new FileReader(\"file\");\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " foo18(reader31);\n" +
+ " }\n" +
+ " }.run();\n" +
+ " }\n" +
+ " void foo18(FileReader r18) {\n" +
+ " // could theoretically close r18;\n" +
+ " }\n" +
+ " abstract class ResourceProvider {\n" +
+ " abstract FileReader provide();" +
+ " }\n" +
+ " ResourceProvider provider;" +
+ " void foo23() throws Exception {\n" +
+ " final FileReader reader23 = new FileReader(\"file\");\n" +
+ " provider = new ResourceProvider() {\n" +
+ " public FileReader provide() {\n" +
+ " return reader23;\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 4)\n" +
+ " final FileReader reader31 = new FileReader(\"file\");\n" +
+ " ^^^^^^^^\n" +
+ "Potential resource leak: 'reader31' may not be closed\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 17)\n" +
+ " final FileReader reader23 = new FileReader(\"file\");\n" +
+ " ^^^^^^^^\n" +
+ "Potential resource leak: 'reader23' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// resource assigned to second local and is (potentially) closed on the latter
+public void test056z() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo17() throws Exception {\n" +
+ " FileReader reader17 = new FileReader(\"file\");\n" +
+ " final FileReader readerCopy = reader17;\n" +
+ " readerCopy.close();\n" +
+ " }\n" +
+ " void foo17a() throws Exception {\n" +
+ " FileReader reader17a = new FileReader(\"file\");\n" +
+ " FileReader readerCopya;" +
+ " readerCopya = reader17a;\n" +
+ " bar(readerCopya);\n" + // potentially closes
+ " }\n" +
+ " void bar(FileReader r) {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 9)\n" +
+ " FileReader reader17a = new FileReader(\"file\");\n" +
+ " ^^^^^^^^^\n" +
+ "Potential resource leak: 'reader17a' may not be closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// multiple early exists from nested scopes (always closed)
+public void test056zz() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo16() throws Exception {\n" +
+ " FileReader reader16 = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " reader16.close();\n " +
+ " return;\n" +
+ " } catch (RuntimeException re) {\n" +
+ " return;\n" +
+ " } catch (Error e) {\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " reader16.close();\n " +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " FileReader reader16 = new FileReader(\"file\");\n" +
+ " ^^^^^^^^\n" +
+ "Resource 'reader16' should be managed by try-with-resource\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 349326 - [1.7] new warning for missing try-with-resources
+// multiple early exists from nested scopes (never closed)
+public void test056zzz() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo16() throws Exception {\n" +
+ " FileReader reader16 = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " return;\n" +
+ " } catch (RuntimeException re) {\n" +
+ " return;\n" +
+ " } catch (Error e) {\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " System.out.println();\n " +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " FileReader reader16 = new FileReader(\"file\");\n" +
+ " ^^^^^^^^\n" +
+ "Resource leak: 'reader16' is never closed\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+// explicit throw is a true method exit here
+public void test056throw1() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo2(boolean a, boolean b, boolean c) throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " if(a)\n" +
+ " throw new Exception(); //warning 1\n" +
+ " else if (b)\n" +
+ " reader.close();\n" +
+ " else if(c)\n" +
+ " throw new Exception(); //warning 2\n" +
+ " reader.close();\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " throw new Exception(); //warning 1\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'reader' is not closed at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 10)\n" +
+ " throw new Exception(); //warning 2\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: 'reader' is not closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+// close() within finally provides protection for throw
+public void test056throw2() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo1() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " try {\n" +
+ " reader.read();\n" +
+ " return;\n" +
+ " } catch (Exception e) {\n" +
+ " throw new Exception();\n" +
+ " } finally {\n" +
+ " reader.close();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " void foo2() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " try {\n" +
+ " reader.read();\n" +
+ " throw new Exception(); // should not warn here\n" +
+ " } catch (Exception e) {\n" +
+ " throw new Exception();\n" +
+ " } finally {\n" +
+ " reader.close();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " void foo3() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " try {\n" +
+ " reader.read();\n" +
+ " throw new Exception();\n" +
+ " } finally {\n" +
+ " reader.close();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " ^^^^^^\n" +
+ "Resource 'reader' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 16)\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " ^^^^^^\n" +
+ "Resource 'reader' should be managed by try-with-resource\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 28)\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " ^^^^^^\n" +
+ "Resource 'reader' should be managed by try-with-resource\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+// close() nested within finally provides protection for throw
+public void test056throw3() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo2x() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " try {\n" +
+ " reader.read();\n" +
+ " throw new Exception(); // should not warn here\n" +
+ " } catch (Exception e) {\n" +
+ " throw new Exception();\n" +
+ " } finally {\n" +
+ " if (reader != null)\n" +
+ " try {\n" +
+ " reader.close();\n" +
+ " } catch (java.io.IOException io) {}\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" +
+ " ^^^^^^\n" +
+ "Resource 'reader' should be managed by try-with-resource\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+// additional boolean should shed doubt on whether we reach the close() call
+public void test056throw4() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo2x(boolean b) throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " reader.read();\n" +
+ " throw new Exception(); // should warn here\n" +
+ " } catch (Exception e) {\n" +
+ " throw new Exception(); // should warn here\n" +
+ " } finally {\n" +
+ " if (reader != null && b)\n" + // this condition is too strong to protect reader
+ " try {\n" +
+ " reader.close();\n" +
+ " } catch (java.io.IOException io) {}\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " throw new Exception(); // should warn here\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: 'reader' may not be closed at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " throw new Exception(); // should warn here\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: 'reader' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+// similar to test056throw3() but indirectly calling close(), so doubts remain.
+public void test056throw5() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileReader;\n" +
+ "public class X {\n" +
+ " void foo2x() throws Exception {\n" +
+ " FileReader reader = new FileReader(\"file\");\n" +
+ " try {\n" +
+ " reader.read();\n" +
+ " throw new Exception(); // should warn 'may not' here\n" +
+ " } catch (Exception e) {\n" +
+ " throw new Exception(); // should warn 'may not' here\n" +
+ " } finally {\n" +
+ " doClose(reader);\n" +
+ " }\n" +
+ " }\n" +
+ " void doClose(FileReader r) { try { r.close(); } catch (java.io.IOException ex) {}}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " throw new Exception(); // should warn \'may not\' here\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: 'reader' may not be closed at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " throw new Exception(); // should warn \'may not\' here\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Potential resource leak: 'reader' may not be closed at this location\n" +
+ "----------\n",
+ null,
+ true,
+ options);
+}
public static Class testClass() {
return TryWithResourcesStatementTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java
index 773fd4835..f62b0ed0e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java
@@ -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
@@ -348,7 +348,7 @@ private String getVerifyTestsCode() {
" this.socket.setTcpNoDelay(true);\n" +
" server.close();\n" +
"\n" +
- " DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" +
+ " final DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" +
" final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" +
" while (true) {\n" +
" final String className = in.readUTF();\n" +

Back to the top