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

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java (-3 / +8 lines)
Lines 8-16 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
12
 *     Stephan Herrmann  - Contribution for bug 295551
12
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
13
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
13
 *     							bug 295551 - Add option to automatically promote all warnings to errors
14
 *     							bug 185682 - Increment/decrement operators mark local variables as read
15
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
14
 *******************************************************************************/
16
 *******************************************************************************/
15
package org.eclipse.jdt.core.tests.compiler.regression;
17
package org.eclipse.jdt.core.tests.compiler.regression;
16
18
Lines 1816-1821 Link Here
1816
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + 
1818
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + 
1817
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + 
1819
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + 
1818
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + 
1820
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + 
1821
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + 
1819
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + 
1822
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + 
1820
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" + 
1823
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" + 
1821
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" + 
1824
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" + 
Lines 1857-1862 Link Here
1857
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + 
1860
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + 
1858
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + 
1861
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + 
1859
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + 
1862
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + 
1863
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" +
1860
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" +
1864
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" +
1861
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + 
1865
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + 
1862
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" + 
1866
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" + 
Lines 1872-1877 Link Here
1872
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + 
1876
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + 
1873
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" +
1877
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" +
1874
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + 
1878
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + 
1879
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" + 
1875
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + 
1880
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + 
1876
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + 
1881
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + 
1877
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + 
1882
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + 
(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java (-1 / +13 lines)
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann  - Contributions for 
12
 *     							bug 236385: [compiler] Warn for potential programming problem if an object is created but not used
13
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
12
 *******************************************************************************/
14
 *******************************************************************************/
13
package org.eclipse.jdt.core.tests.compiler.regression;
15
package org.eclipse.jdt.core.tests.compiler.regression;
14
16
Lines 440-445 Link Here
440
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED);
442
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED);
441
		expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED);
443
		expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED);
442
		expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED);
444
		expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED);
445
		expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
443
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
446
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
444
		expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
447
		expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
445
		expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
448
		expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
Lines 765-770 Link Here
765
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
768
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
766
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
769
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
767
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
770
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
771
		expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
772
		expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
768
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
773
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
769
		expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
774
		expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
770
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
775
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
Lines 828-833 Link Here
828
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
833
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
829
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT));
834
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT));
830
		expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
835
		expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
836
		expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
837
		expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
831
		expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
838
		expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
832
		expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
839
		expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
833
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
840
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
Lines 1108-1113 Link Here
1108
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP);
1115
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP);
1109
		expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP);
1116
		expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP);
1110
		expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP);
1117
		expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP);
1118
		expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE));
1111
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP);
1119
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP);
1112
		expectedProblemAttributes.put("ExternalProblemFixable", SKIP);
1120
		expectedProblemAttributes.put("ExternalProblemFixable", SKIP);
1113
		expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP);
1121
		expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP);
Lines 1433-1438 Link Here
1433
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP);
1441
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP);
1434
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
1442
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
1435
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
1443
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
1444
		expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
1445
		expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
1436
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
1446
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
1437
		expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
1447
		expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
1438
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
1448
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
Lines 1496-1501 Link Here
1496
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION));
1506
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION));
1497
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING));
1507
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING));
1498
		expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING));
1508
		expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING));
1509
		expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE));
1510
		expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE));
1499
		expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP);
1511
		expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP);
1500
		expectedProblemAttributes.put("UndefinedConstructor", SKIP);
1512
		expectedProblemAttributes.put("UndefinedConstructor", SKIP);
1501
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP);
1513
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP);
(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java (-1 / +49 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 236385
10
 *     Stephan Herrmann - Contributions for
11
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
12
 *      						bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.core.tests.compiler.regression;
14
package org.eclipse.jdt.core.tests.compiler.regression;
13
15
Lines 2360-2365 Link Here
2360
		"The local variable i may not have been initialized\n" + 
2362
		"The local variable i may not have been initialized\n" + 
2361
		"----------\n");
2363
		"----------\n");
2362
}
2364
}
2365
// Bug 349326 - [1.7] new warning for missing try-with-resources
2366
// variant < 1.7 using Closeable: not closed
2367
public void testCloseable1() {
2368
	this.runNegativeTest(
2369
			new String[] {
2370
				"X.java",
2371
				"import java.io.File;\n" + 
2372
				"import java.io.FileReader;\n" + 
2373
				"import java.io.IOException;\n" + 
2374
				"public class X {\n" +
2375
				"    void foo() throws IOException {\n" +
2376
				"        File file = new File(\"somefile\");\n" + 
2377
				"        FileReader fileReader = new FileReader(file); // not closed\n" + 
2378
				"        char[] in = new char[50];\n" + 
2379
				"        fileReader.read(in);\n" + 
2380
				"    }\n" + 
2381
				"}\n"
2382
			}, 
2383
			"----------\n" + 
2384
			"1. WARNING in X.java (at line 7)\n" + 
2385
			"	FileReader fileReader = new FileReader(file); // not closed\n" + 
2386
			"	           ^^^^^^^^^^\n" + 
2387
			"Resource leak: 'fileReader' is never closed\n" + 
2388
			"----------\n");	
2389
}
2390
// Bug 349326 - [1.7] new warning for missing try-with-resources
2391
// variant < 1.7 using Closeable: resource is closed, cannot suggest try-with-resources < 1.7
2392
public void testCloseable2() {
2393
	this.runConformTest(
2394
			new String[] {
2395
				"X.java",
2396
				"import java.io.File;\n" + 
2397
				"import java.io.FileReader;\n" + 
2398
				"import java.io.IOException;\n" + 
2399
				"public class X {\n" +
2400
				"    void foo() throws IOException {\n" +
2401
				"        File file = new File(\"somefile\");\n" + 
2402
				"        FileReader fileReader = new FileReader(file); // not closed\n" + 
2403
				"        char[] in = new char[50];\n" + 
2404
				"        fileReader.read(in);\n" +
2405
				"        fileReader.close();\n" + 
2406
				"    }\n" + 
2407
				"}\n"
2408
			}, 
2409
			"");	
2410
}
2363
public static Class testClass() {
2411
public static Class testClass() {
2364
	return FlowAnalysisTest.class;
2412
	return FlowAnalysisTest.class;
2365
}
2413
}
(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (-6 / +12 lines)
Lines 19-24 Link Here
19
 * 							bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
19
 * 							bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
20
 * 							bug 354554 - [null] conditional with redundant condition yields weak error message
20
 * 							bug 354554 - [null] conditional with redundant condition yields weak error message
21
 * 							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
21
 * 							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
22
 * 							bug 349326 - [1.7] new warning for missing try-with-resources
22
 *******************************************************************************/
23
 *******************************************************************************/
23
package org.eclipse.jdt.core.tests.compiler.regression;
24
package org.eclipse.jdt.core.tests.compiler.regression;
24
25
Lines 6030-6041 Link Here
6030
			"    }\n" +
6031
			"    }\n" +
6031
			"  }\n" +
6032
			"  }\n" +
6032
			"}\n"},
6033
			"}\n"},
6033
		"----------\n" +
6034
			"----------\n" +
6034
		"1. ERROR in X.java (at line 8)\n" +
6035
			"1. WARNING in X.java (at line 6)\n" +
6035
		"	o.toString();\n" +
6036
			"	o = new LineNumberReader(new FileReader(\"dummy\"));\n" +
6036
		"	^\n" +
6037
			"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
6037
		"Potential null pointer access: The variable o may be null at this location\n" +
6038
			"Resource leak: \'o\' is never closed\n" +
6038
		"----------\n",
6039
			"----------\n" +
6040
			"2. ERROR in X.java (at line 8)\n" +
6041
			"	o.toString();\n" +
6042
			"	^\n" +
6043
			"Potential null pointer access: The variable o may be null at this location\n" +
6044
			"----------\n",
6039
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
6045
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
6040
}
6046
}
6041
6047
(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java (-6 / +1500 lines)
Lines 7-25 Link Here
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
10
 *     Stephan Herrmann - Contributions for
11
 *     							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.core.tests.compiler.regression;
14
package org.eclipse.jdt.core.tests.compiler.regression;
13
15
14
import java.util.Map;
16
import java.util.Map;
15
17
18
import org.eclipse.jdt.core.JavaCore;
16
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
19
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
17
20
18
import junit.framework.Test;
21
import junit.framework.Test;
19
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
22
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
20
23
21
static {
24
static {
22
//	TESTS_NAMES = new String[] { "test055", "test055a" };
25
//	TESTS_NAMES = new String[] { "test056zz"};
23
//	TESTS_NUMBERS = new int[] { 50 };
26
//	TESTS_NUMBERS = new int[] { 50 };
24
//	TESTS_RANGE = new int[] { 11, -1 };
27
//	TESTS_RANGE = new int[] { 11, -1 };
25
}
28
}
Lines 486-497 Link Here
486
		"	               ^^\n" + 
489
		"	               ^^\n" + 
487
		"Dead code\n" + 
490
		"Dead code\n" + 
488
		"----------\n" + 
491
		"----------\n" + 
489
		"3. ERROR in X.java (at line 5)\n" + 
492
		"3. WARNING in X.java (at line 5)\n" + 
493
		"	Y why = new Y();\n" + 
494
		"	  ^^^\n" + 
495
		"Resource leak: 'why' is never closed\n" + 
496
		"----------\n" + 
497
		"4. ERROR in X.java (at line 5)\n" + 
490
		"	Y why = new Y();\n" + 
498
		"	Y why = new Y();\n" + 
491
		"	        ^^^^^^^\n" + 
499
		"	        ^^^^^^^\n" + 
492
		"Unhandled exception type WeirdException\n" + 
500
		"Unhandled exception type WeirdException\n" + 
493
		"----------\n" + 
501
		"----------\n" + 
494
		"4. WARNING in X.java (at line 22)\n" + 
502
		"5. WARNING in X.java (at line 22)\n" + 
495
		"	class WeirdException extends Throwable {}\n" + 
503
		"	class WeirdException extends Throwable {}\n" + 
496
		"	      ^^^^^^^^^^^^^^\n" + 
504
		"	      ^^^^^^^^^^^^^^\n" + 
497
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
505
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
Lines 559-570 Link Here
559
		"	               ^^\n" + 
567
		"	               ^^\n" + 
560
		"Dead code\n" + 
568
		"Dead code\n" + 
561
		"----------\n" + 
569
		"----------\n" + 
562
		"3. ERROR in X.java (at line 5)\n" + 
570
		"3. WARNING in X.java (at line 5)\n" + 
571
		"	Y why = new Y();\n" + 
572
		"	  ^^^\n" + 
573
		"Resource leak: 'why' is never closed\n" + 
574
		"----------\n" + 
575
		"4. ERROR in X.java (at line 5)\n" + 
563
		"	Y why = new Y();\n" + 
576
		"	Y why = new Y();\n" + 
564
		"	        ^^^^^^^\n" + 
577
		"	        ^^^^^^^\n" + 
565
		"Unhandled exception type WeirdException\n" + 
578
		"Unhandled exception type WeirdException\n" + 
566
		"----------\n" + 
579
		"----------\n" + 
567
		"4. WARNING in X.java (at line 20)\n" + 
580
		"5. WARNING in X.java (at line 20)\n" + 
568
		"	class WeirdException extends Throwable {}\n" + 
581
		"	class WeirdException extends Throwable {}\n" + 
569
		"	      ^^^^^^^^^^^^^^\n" + 
582
		"	      ^^^^^^^^^^^^^^\n" + 
570
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
583
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
Lines 3432-3437 Link Here
3432
		},
3445
		},
3433
		"Done");
3446
		"Done");
3434
}
3447
}
3448
// Bug 349326 - [1.7] new warning for missing try-with-resources
3449
// a method uses an AutoCloseable without ever closing it.
3450
public void test056() {
3451
	Map options = getCompilerOptions();
3452
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3453
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3454
	this.runNegativeTest(
3455
		new String[] {
3456
			"X.java",
3457
			"import java.io.File;\n" +
3458
			"import java.io.FileReader;\n" +
3459
			"import java.io.IOException;\n" +
3460
			"public class X {\n" +
3461
			"    void foo() throws IOException {\n" +
3462
			"        File file = new File(\"somefile\");\n" +
3463
			"        FileReader fileReader = new FileReader(file);\n" +
3464
// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler
3465
//			"        char[] in = new char[50];\n" +
3466
//			"        fileReader.read(in);\n" +
3467
			"    }\n" +
3468
			"    public static void main(String[] args) throws IOException {\n" +
3469
			"        new X().foo();\n" +
3470
			"    }\n" +
3471
			"}\n"
3472
		},
3473
		"----------\n" + 
3474
		"1. ERROR in X.java (at line 7)\n" + 
3475
		"	FileReader fileReader = new FileReader(file);\n" + 
3476
		"	           ^^^^^^^^^^\n" + 
3477
		"Resource leak: 'fileReader' is never closed\n" +
3478
		"----------\n",
3479
		null,
3480
		true,
3481
		options);
3482
}
3483
// Bug 349326 - [1.7] new warning for missing try-with-resources
3484
// a method uses an AutoCloseable and closes it but not protected by t-w-r nor regular try-finally
3485
public void test056a() {
3486
	Map options = getCompilerOptions();
3487
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3488
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3489
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3490
	this.runNegativeTest(
3491
		new String[] {
3492
			"X.java",
3493
			"import java.io.File;\n" +
3494
			"import java.io.FileReader;\n" +
3495
			"import java.io.IOException;\n" +
3496
			"public class X {\n" +
3497
			"    void foo() throws IOException {\n" +
3498
			"        File file = new File(\"somefile\");\n" +
3499
			"        FileReader fileReader = new FileReader(file);\n" +
3500
			"        char[] in = new char[50];\n" +
3501
			"        fileReader.read(in);\n" +
3502
			"		 fileReader.close();\n" +
3503
			"    }\n" +
3504
			"    public static void main(String[] args) {\n" +
3505
			"        try {\n" +
3506
			"            new X().foo();\n" +
3507
			"        } catch (IOException ioex) {\n" +
3508
			"            System.out.println(\"caught\");\n" +
3509
			"        }\n" +
3510
			"    }\n" +
3511
			"}\n"
3512
		},
3513
		"----------\n" + 
3514
		"1. ERROR in X.java (at line 7)\n" + 
3515
		"	FileReader fileReader = new FileReader(file);\n" + 
3516
		"	           ^^^^^^^^^^\n" + 
3517
		"Resource 'fileReader' should be managed by try-with-resource\n" + 
3518
		"----------\n",
3519
		null,
3520
		true,
3521
		options);
3522
}
3523
// Bug 349326 - [1.7] new warning for missing try-with-resources
3524
// a method uses an AutoCloseable and closes it properly in a finally block
3525
public void test056b() {
3526
	Map options = getCompilerOptions();
3527
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3528
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3529
	this.runConformTest(
3530
		new String[] {
3531
			"X.java",
3532
			"import java.io.File;\n" +
3533
			"import java.io.FileReader;\n" +
3534
			"import java.io.IOException;\n" +
3535
			"public class X {\n" +
3536
			"    void foo() throws IOException {\n" +
3537
			"        File file = new File(\"somefile\");\n" +
3538
			"        FileReader fileReader = new FileReader(file);\n" +
3539
			"        try {\n" +
3540
			"            char[] in = new char[50];\n" +
3541
			"            fileReader.read(in);\n" +
3542
			"        } finally {\n" +
3543
			"		     fileReader.close();\n" +
3544
			"        }\n" +
3545
			"    }\n" +
3546
			"    public static void main(String[] args) {\n" +
3547
			"        try {\n" +
3548
			"            new X().foo();\n" +
3549
			"        } catch (IOException ioex) {\n" +
3550
			"            System.out.println(\"caught\");\n" +
3551
			"        }\n" +
3552
			"    }\n" +
3553
			"}\n"
3554
		},
3555
		"caught", /*output*/
3556
		null/*classLibs*/,
3557
		true/*shouldFlush*/,
3558
		null/*vmargs*/,
3559
		options,
3560
		null/*requestor*/);
3561
}
3562
// Bug 349326 - [1.7] new warning for missing try-with-resources
3563
// a method uses an AutoCloseable properly within try-with-resources.
3564
public void test056c() {
3565
	Map options = getCompilerOptions();
3566
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3567
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3568
	this.runConformTest(
3569
		new String[] {
3570
			"X.java",
3571
			"import java.io.File;\n" +
3572
			"import java.io.FileReader;\n" +
3573
			"import java.io.IOException;\n" +
3574
			"public class X {\n" +
3575
			"    void foo() throws IOException {\n" +
3576
			"        File file = new File(\"somefile\");\n" +
3577
			"        try (FileReader fileReader = new FileReader(file)) {\n" +
3578
			"            char[] in = new char[50];\n" +
3579
			"            fileReader.read(in);\n" +
3580
			"		 }\n" +
3581
			"    }\n" +
3582
			"    public static void main(String[] args) {\n" +
3583
			"        try {\n" +
3584
			"            new X().foo();\n" +
3585
			"        } catch (IOException ioex) {\n" +
3586
			"            System.out.println(\"caught\");\n" +
3587
			"        }\n" +
3588
			"    }\n" +
3589
			"}\n"
3590
		},
3591
		"caught", /*output*/
3592
		null/*classLibs*/,
3593
		true/*shouldFlush*/,
3594
		null/*vmargs*/,
3595
		options,
3596
		null/*requestor*/);
3597
}
3598
// Bug 349326 - [1.7] new warning for missing try-with-resources
3599
// a method uses two AutoCloseables (testing independent analysis)
3600
// - one closeable may be unclosed at a conditional return
3601
// - the other is only conditionally closed
3602
public void test056d() {
3603
	Map options = getCompilerOptions();
3604
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3605
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3606
	this.runNegativeTest(
3607
		new String[] {
3608
			"X.java",
3609
			"import java.io.File;\n" +
3610
			"import java.io.FileReader;\n" +
3611
			"import java.io.IOException;\n" +
3612
			"public class X {\n" +
3613
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3614
			"        File file = new File(\"somefile\");\n" +
3615
			"        char[] in = new char[50];\n" +
3616
			"        FileReader fileReader1 = new FileReader(file);\n" +
3617
			"        fileReader1.read(in);\n" +
3618
			"        FileReader fileReader2 = new FileReader(file);\n" +
3619
			"        fileReader2.read(in);\n" +
3620
			"        if (flag1) {\n" +
3621
			"            fileReader2.close();\n" +
3622
			"            return;\n" +
3623
			"        } else if (flag2) {\n" +
3624
			"            fileReader2.close();\n" +
3625
			"        }\n" +
3626
			"        fileReader1.close();\n" +
3627
			"    }\n" +
3628
			"    public static void main(String[] args) throws IOException {\n" +
3629
			"        new X().foo(false, true);\n" +
3630
			"    }\n" +
3631
			"}\n"
3632
		},
3633
		"----------\n" + 
3634
		"1. WARNING in X.java (at line 10)\n" + 
3635
		"	FileReader fileReader2 = new FileReader(file);\n" + 
3636
		"	           ^^^^^^^^^^^\n" + 
3637
		"Potential resource leak: 'fileReader2' may not be closed\n" +
3638
		"----------\n" + 
3639
		"2. ERROR in X.java (at line 14)\n" + 
3640
		"	return;\n" + 
3641
		"	^^^^^^^\n" + 
3642
		"Resource leak: \'fileReader1\' is not closed at this location\n" + 
3643
		"----------\n",
3644
		null,
3645
		true,
3646
		options);
3647
}
3648
//Bug 349326 - [1.7] new warning for missing try-with-resources
3649
//a method uses two AutoCloseables (testing independent analysis)
3650
//- one closeable may be unclosed at a conditional return
3651
//- the other is only conditionally closed
3652
public void test056d_suppress() {
3653
	Map options = getCompilerOptions();
3654
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3655
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3656
	options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
3657
	this.runNegativeTest(
3658
		new String[] {
3659
			"X.java",
3660
			"import java.io.File;\n" +
3661
			"import java.io.FileReader;\n" +
3662
			"import java.io.IOException;\n" +
3663
			"public class X {\n" +
3664
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3665
			"        @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" +
3666
			"        char[] in = new char[50];\n" +
3667
			"        FileReader fileReader1 = new FileReader(file);\n" +
3668
			"        fileReader1.read(in);\n" +
3669
			"        @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" +
3670
			"        fileReader2.read(in);\n" +
3671
			"        if (flag1) {\n" +
3672
			"            fileReader2.close();\n" +
3673
			"            return; // not suppressed\n" +
3674
			"        } else if (flag2) {\n" +
3675
			"            fileReader2.close();\n" +
3676
			"        }\n" +
3677
			"        fileReader1.close();\n" +
3678
			"    }\n" +
3679
			"    @SuppressWarnings(\"resource\") // useful suppress\n" +
3680
			"    void bar() throws IOException {\n" +
3681
			"        File file = new File(\"somefile\");\n" +
3682
			"        FileReader fileReader = new FileReader(file);\n" +
3683
			"        char[] in = new char[50];\n" +
3684
			"        fileReader.read(in);\n" +
3685
			"    }\n" +
3686
			"    public static void main(String[] args) throws IOException {\n" +
3687
			"        new X().foo(false, true);\n" +
3688
			"    }\n" +
3689
			"}\n"
3690
		},
3691
		"----------\n" + 
3692
		"1. WARNING in X.java (at line 6)\n" + 
3693
		"	@SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + 
3694
		"	                  ^^^^^^^^^^\n" + 
3695
		"Unnecessary @SuppressWarnings(\"resource\")\n" + 
3696
		"----------\n" + 
3697
		"2. ERROR in X.java (at line 14)\n" + 
3698
		"	return; // not suppressed\n" + 
3699
		"	^^^^^^^\n" + 
3700
		"Resource leak: \'fileReader1\' is not closed at this location\n" + 
3701
		"----------\n",
3702
		null,
3703
		true,
3704
		options);
3705
}
3706
// Bug 349326 - [1.7] new warning for missing try-with-resources
3707
// one method returns an AutoCleasble, a second method uses this object without ever closing it.
3708
public void test056e() {
3709
	Map options = getCompilerOptions();
3710
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3711
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3712
	this.runNegativeTest(
3713
		new String[] {
3714
			"X.java",
3715
			"import java.io.File;\n" +
3716
			"import java.io.FileReader;\n" +
3717
			"import java.io.IOException;\n" +
3718
			"public class X {\n" +
3719
			"    FileReader getReader(String filename) throws IOException {\n" +
3720
			"        File file = new File(\"somefile\");\n" +
3721
			"        FileReader fileReader = new FileReader(file);\n" +
3722
			"        return fileReader;\n" + 		// don't complain here, pass responsibility to caller
3723
			"    }\n" +
3724
			"    void foo() throws IOException {\n" +
3725
			"        FileReader reader = getReader(\"somefile\");\n" +
3726
			"        char[] in = new char[50];\n" +
3727
			"        reader.read(in);\n" +
3728
			"    }\n" +
3729
			"    public static void main(String[] args) throws IOException {\n" +
3730
			"        new X().foo();\n" +
3731
			"    }\n" +
3732
			"}\n"
3733
		},
3734
		"----------\n" + 
3735
		"1. ERROR in X.java (at line 11)\n" + 
3736
		"	FileReader reader = getReader(\"somefile\");\n" + 
3737
		"	           ^^^^^^\n" + 
3738
		"Resource leak: 'reader' is never closed\n" + 
3739
		"----------\n",
3740
		null,
3741
		true,
3742
		options);
3743
}
3744
// Bug 349326 - [1.7] new warning for missing try-with-resources
3745
// a method explicitly closes its AutoCloseable rather than using t-w-r
3746
public void test056f() {
3747
	Map options = getCompilerOptions();
3748
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3749
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3750
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3751
	this.runNegativeTest(
3752
		new String[] {
3753
			"X.java",
3754
			"import java.io.File;\n" +
3755
			"import java.io.FileReader;\n" +
3756
			"import java.io.IOException;\n" +
3757
			"public class X {\n" +
3758
			"    void foo() throws IOException {\n" +
3759
			"        File file = new File(\"somefile\");\n" +
3760
			"        FileReader fileReader = null;\n" +
3761
			"        try {\n" +
3762
			"            fileReader = new FileReader(file);\n" +
3763
			"            char[] in = new char[50];\n" +
3764
			"            fileReader.read(in);\n" +
3765
			"        } finally {\n" +
3766
			"            fileReader.close();\n" +
3767
			"        }\n" +
3768
			"    }\n" +
3769
			"    public static void main(String[] args) throws IOException {\n" +
3770
			"        new X().foo();\n" +
3771
			"    }\n" +
3772
			"}\n"
3773
		},
3774
		"----------\n" + 
3775
		"1. ERROR in X.java (at line 7)\n" + 
3776
		"	FileReader fileReader = null;\n" + 
3777
		"	           ^^^^^^^^^^\n" + 
3778
		"Resource \'fileReader\' should be managed by try-with-resource\n" + 
3779
		"----------\n",
3780
		null,
3781
		true,
3782
		options);
3783
}
3784
// Bug 349326 - [1.7] new warning for missing try-with-resources
3785
// an AutoCloseable local is re-assigned
3786
public void test056g() {
3787
	Map options = getCompilerOptions();
3788
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3789
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3790
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3791
	this.runNegativeTest(
3792
		new String[] {
3793
			"X.java",
3794
			"import java.io.File;\n" +
3795
			"import java.io.FileReader;\n" +
3796
			"import java.io.IOException;\n" +
3797
			"public class X {\n" +
3798
			"    void foo() throws IOException {\n" +
3799
			"        File file = new File(\"somefile\");\n" +
3800
			"        FileReader fileReader = new FileReader(file);\n" +
3801
			"        char[] in = new char[50];\n" +
3802
			"        fileReader.read(in);\n" +
3803
			"        fileReader = new FileReader(file);\n" +
3804
			"        fileReader.read(in);\n" +
3805
			"        fileReader.close();\n" +
3806
			"        fileReader = null;\n" +
3807
			"    }\n" +
3808
			"    public static void main(String[] args) throws IOException {\n" +
3809
			"        new X().foo();\n" +
3810
			"    }\n" +
3811
			"}\n"
3812
		},
3813
		"----------\n" + 
3814
		"1. ERROR in X.java (at line 10)\n" + 
3815
		"	fileReader = new FileReader(file);\n" + 
3816
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
3817
		"Resource leak: \'fileReader\' is not closed at this location\n" + 
3818
		"----------\n",
3819
		null,
3820
		true,
3821
		options);
3822
}
3823
// Bug 349326 - [1.7] new warning for missing try-with-resources
3824
// an AutoCloseable local is re-assigned after null-assigned
3825
public void test056g2() {
3826
	Map options = getCompilerOptions();
3827
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3828
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3829
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3830
	this.runNegativeTest(
3831
		new String[] {
3832
			"X.java",
3833
			"import java.io.File;\n" +
3834
			"import java.io.FileReader;\n" +
3835
			"import java.io.IOException;\n" +
3836
			"public class X {\n" +
3837
			"    void foo() throws IOException {\n" +
3838
			"        File file = new File(\"somefile\");\n" +
3839
			"        FileReader fileReader = new FileReader(file);\n" +
3840
			"        char[] in = new char[50];\n" +
3841
			"        fileReader.read(in);\n" +
3842
			"        fileReader = null;\n" +
3843
			"        fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here
3844
			"        fileReader.read(in);\n" +
3845
			"        fileReader.close();\n" +
3846
			"    }\n" +
3847
			"    public static void main(String[] args) throws IOException {\n" +
3848
			"        new X().foo();\n" +
3849
			"    }\n" +
3850
			"}\n"
3851
		},
3852
		"----------\n" + 
3853
		"1. ERROR in X.java (at line 10)\n" + 
3854
		"	fileReader = null;\n" + 
3855
		"	^^^^^^^^^^^^^^^^^\n" + 
3856
		"Resource leak: \'fileReader\' is not closed at this location\n" + 
3857
		"----------\n",
3858
		null,
3859
		true,
3860
		options);
3861
}
3862
// Bug 349326 - [1.7] new warning for missing try-with-resources
3863
// two AutoCloseables at different nesting levels (anonymous local type)
3864
public void test056h() {
3865
	Map options = getCompilerOptions();
3866
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3867
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3868
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3869
	this.runNegativeTest(
3870
		new String[] {
3871
			"X.java",
3872
			"import java.io.File;\n" +
3873
			"import java.io.FileReader;\n" +
3874
			"import java.io.IOException;\n" +
3875
			"public class X {\n" +
3876
			"    void foo() throws IOException {\n" +
3877
			"        final File file = new File(\"somefile\");\n" +
3878
			"        final FileReader fileReader = new FileReader(file);\n" +
3879
			"        char[] in = new char[50];\n" +
3880
			"        fileReader.read(in);\n" +
3881
			"        new Runnable() {\n public void run() {\n" +
3882
			"            try {\n" +
3883
			"                fileReader.close();\n" +
3884
			"                FileReader localReader = new FileReader(file);\n" +
3885
			"            } catch (IOException ex) { /* nop */ }\n" +
3886
			"        }}.run();\n" +
3887
			"    }\n" +
3888
			"    public static void main(String[] args) throws IOException {\n" +
3889
			"        new X().foo();\n" +
3890
			"    }\n" +
3891
			"}\n"
3892
		},
3893
		"----------\n" + 
3894
		"1. WARNING in X.java (at line 7)\n" + 
3895
		"	final FileReader fileReader = new FileReader(file);\n" + 
3896
		"	                 ^^^^^^^^^^\n" + 
3897
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3898
		"----------\n" + 
3899
		"2. ERROR in X.java (at line 14)\n" + 
3900
		"	FileReader localReader = new FileReader(file);\n" + 
3901
		"	           ^^^^^^^^^^^\n" + 
3902
		"Resource leak: 'localReader' is never closed\n" + 
3903
		"----------\n",
3904
		null,
3905
		true,
3906
		options);
3907
}
3908
// Bug 349326 - [1.7] new warning for missing try-with-resources
3909
// three AutoCloseables in different blocks of the same method
3910
public void test056i() {
3911
	Map options = getCompilerOptions();
3912
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3913
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3914
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3915
	this.runNegativeTest(
3916
		new String[] {
3917
			"X.java",
3918
			"import java.io.File;\n" +
3919
			"import java.io.FileReader;\n" +
3920
			"import java.io.IOException;\n" +
3921
			"public class X {\n" +
3922
			"    void foo(boolean f1, boolean f2) throws IOException {\n" +
3923
			"        File file = new File(\"somefile\");\n" +
3924
			"        if (f1) {\n" +
3925
			"            FileReader fileReader = new FileReader(file); // err: not closed\n" +
3926
			"            char[] in = new char[50];\n" +
3927
			"            fileReader.read(in);\n" +
3928
			"            while (true) {\n" +
3929
			"                 FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
3930
			"                 loopReader.close();" +
3931
			"                 break;\n" +
3932
			"            }\n" +
3933
			"        } else {\n" +
3934
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
3935
			"            if (f2)\n" +
3936
			"                fileReader.close();\n" +
3937
			"        }\n" +
3938
			"    }\n" +
3939
			"    public static void main(String[] args) throws IOException {\n" +
3940
			"        new X().foo(true, true);\n" +
3941
			"    }\n" +
3942
			"}\n"
3943
		},
3944
		"----------\n" + 
3945
		"1. ERROR in X.java (at line 8)\n" + 
3946
		"	FileReader fileReader = new FileReader(file); // err: not closed\n" + 
3947
		"	           ^^^^^^^^^^\n" + 
3948
		"Resource leak: 'fileReader' is never closed\n" + 
3949
		"----------\n" + 
3950
		"2. WARNING in X.java (at line 16)\n" + 
3951
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3952
		"	           ^^^^^^^^^^\n" + 
3953
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3954
		"----------\n",
3955
		null,
3956
		true,
3957
		options);
3958
}
3959
// Bug 349326 - [1.7] new warning for missing try-with-resources
3960
// three AutoCloseables in different blocks of the same method
3961
public void test056i2() {
3962
	Map options = getCompilerOptions();
3963
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3964
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3965
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3966
	this.runNegativeTest(
3967
		new String[] {
3968
			"X.java",
3969
			"import java.io.File;\n" + 
3970
			"import java.io.FileReader;\n" + 
3971
			"import java.io.IOException;\n" + 
3972
			"public class X {\n" +
3973
			"    void foo(boolean f1, boolean f2) throws IOException {\n" + 
3974
			"        File file = new File(\"somefile\");\n" + 
3975
			"        if (f1) {\n" + 
3976
			"            FileReader fileReader = new FileReader(file); // properly closed\n" + 
3977
			"            char[] in = new char[50];\n" + 
3978
			"            fileReader.read(in);\n" + 
3979
			"            while (true) {\n" + 
3980
			"                  fileReader.close();\n" + 
3981
			"                  FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + 
3982
			"                  loopReader.close();\n" + 
3983
			"                  break;\n" + 
3984
			"            }\n" + 
3985
			"        } else {\n" + 
3986
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3987
			"            if (f2)\n" + 
3988
			"                fileReader.close();\n" + 
3989
			"        }\n" + 
3990
			"    }\n" + 
3991
			"    public static void main(String[] args) throws IOException {\n" + 
3992
			"        new X().foo(true, true);\n" + 
3993
			"    }\n" + 
3994
			"}\n"
3995
		},
3996
		"----------\n" + 
3997
		"1. ERROR in X.java (at line 18)\n" + 
3998
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3999
		"	           ^^^^^^^^^^\n" + 
4000
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4001
		"----------\n",
4002
		null,
4003
		true,
4004
		options);
4005
}
4006
// Bug 349326 - [1.7] new warning for missing try-with-resources
4007
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
4008
public void test056j() {
4009
	Map options = getCompilerOptions();
4010
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4011
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4012
	this.runNegativeTest(
4013
		new String[] {
4014
			"X.java",
4015
			"import java.io.File;\n" +
4016
			"import java.io.FileReader;\n" +
4017
			"import java.io.IOException;\n" +
4018
			"public class X {\n" +
4019
			"    void foo() throws IOException {\n" +
4020
			"        File file = new File(\"somefile\");\n" +
4021
			"        FileReader fileReader = new FileReader(file);\n" +
4022
			"        read(fileReader);\n" +
4023
			"    }\n" +
4024
			"    void read(FileReader reader) { }\n" +
4025
			"    public static void main(String[] args) throws IOException {\n" +
4026
			"        new X().foo();\n" +
4027
			"    }\n" +
4028
			"}\n"
4029
		},
4030
		"----------\n" + 
4031
		"1. ERROR in X.java (at line 7)\n" + 
4032
		"	FileReader fileReader = new FileReader(file);\n" + 
4033
		"	           ^^^^^^^^^^\n" + 
4034
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4035
		"----------\n",
4036
		null,
4037
		true,
4038
		options);
4039
}
4040
// Bug 349326 - [1.7] new warning for missing try-with-resources
4041
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
4042
public void test056jconditional() {
4043
	Map options = getCompilerOptions();
4044
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4045
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4046
	this.runNegativeTest(
4047
		new String[] {
4048
			"X.java",
4049
			"import java.io.File;\n" +
4050
			"import java.io.FileReader;\n" +
4051
			"import java.io.IOException;\n" +
4052
			"public class X {\n" +
4053
			"    void foo(boolean b) throws IOException {\n" +
4054
			"        File file = new File(\"somefile\");\n" +
4055
			"        FileReader fileReader = new FileReader(file);\n" +
4056
			"        synchronized (b ? this : new X()) {\n" +
4057
			"            new ReadDelegator(fileReader);\n" +
4058
			"        }\n" +
4059
			"    }\n" +
4060
			"    class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" +
4061
			"    public static void main(String[] args) throws IOException {\n" +
4062
			"        new X().foo(true);\n" +
4063
			"    }\n" +
4064
			"}\n"
4065
		},
4066
		"----------\n" + 
4067
		"1. ERROR in X.java (at line 7)\n" + 
4068
		"	FileReader fileReader = new FileReader(file);\n" + 
4069
		"	           ^^^^^^^^^^\n" + 
4070
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4071
		"----------\n",
4072
		null,
4073
		true,
4074
		options);
4075
}
4076
// Bug 349326 - [1.7] new warning for missing try-with-resources
4077
// many locals, some are AutoCloseable.
4078
// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3,
4079
// doing so would create false positives.
4080
public void test056k() {
4081
	Map options = getCompilerOptions();
4082
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4083
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
4084
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4085
	this.runNegativeTest(
4086
		new String[] {
4087
			"X.java",
4088
			"import java.io.File;\n" +
4089
			"import java.io.FileReader;\n" +
4090
			"import java.io.IOException;\n" +
4091
			"public class X {\n" +
4092
			"    void foo() throws IOException {\n" +
4093
			"        int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" +
4094
			"            i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" +
4095
			"            i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" +
4096
			"            i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" +
4097
			"            i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" +
4098
			"        File file = new File(\"somefile\");\n" +
4099
			"        FileReader ra1 = null, ra2 = null;\n" +
4100
			"        try {\n" +
4101
			"            ra1 = new FileReader(file);\n" +
4102
			"            ra2 = new FileReader(file);\n" +
4103
			"            FileReader ra3 = new FileReader(file);\n" +
4104
			"            char[] in = new char[50];\n" +
4105
			"            ra1.read(in);\n" +
4106
			"            ra2.read(in);\n" +
4107
			"            ra3.close();\n" +
4108
			"        } finally {\n" +
4109
			"            ra1.close();\n" +
4110
			"        }\n" +
4111
			"        int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits
4112
			"        FileReader rb1 = null, rb2 = null;\n" +
4113
			"        try {\n" +
4114
			"            rb1 = new FileReader(file);\n" +
4115
			"            rb2 = new FileReader(file);\n" +
4116
			"            FileReader rb3 = new FileReader(file);\n" +
4117
			"            char[] in = new char[50];\n" +
4118
			"            rb1.read(in);\n" +
4119
			"            rb2.read(in);\n" +
4120
			"            rb3.close();\n" +
4121
			"        } finally {\n" +
4122
			"            rb1.close();\n" +
4123
			"        }\n" +
4124
			"    }\n" +
4125
			"    public static void main(String[] args) throws IOException {\n" +
4126
			"        new X().foo();\n" +
4127
			"    }\n" +
4128
			"}\n"
4129
		},
4130
		"----------\n" + 
4131
		"1. ERROR in X.java (at line 12)\n" + 
4132
		"	FileReader ra1 = null, ra2 = null;\n" + 
4133
		"	           ^^^\n" + 
4134
		"Resource \'ra1\' should be managed by try-with-resource\n" + 
4135
		"----------\n" + 
4136
		"2. ERROR in X.java (at line 15)\n" + 
4137
		"	ra2 = new FileReader(file);\n" + 
4138
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4139
		"Resource leak: 'ra2' is never closed\n" + 
4140
		"----------\n" + 
4141
		"3. ERROR in X.java (at line 16)\n" + 
4142
		"	FileReader ra3 = new FileReader(file);\n" + 
4143
		"	           ^^^\n" + 
4144
		"Resource \'ra3\' should be managed by try-with-resource\n" +
4145
		"----------\n" + 
4146
		"4. ERROR in X.java (at line 25)\n" + 
4147
		"	FileReader rb1 = null, rb2 = null;\n" + 
4148
		"	           ^^^\n" + 
4149
		"Resource \'rb1\' should be managed by try-with-resource\n" + 
4150
		"----------\n" + 
4151
		"5. ERROR in X.java (at line 28)\n" + 
4152
		"	rb2 = new FileReader(file);\n" + 
4153
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4154
		"Resource leak: 'rb2' is never closed\n" + 
4155
		"----------\n" + 
4156
		"6. ERROR in X.java (at line 29)\n" + 
4157
		"	FileReader rb3 = new FileReader(file);\n" + 
4158
		"	           ^^^\n" + 
4159
		"Resource \'rb3\' should be managed by try-with-resource\n" + 
4160
		"----------\n",
4161
		null,
4162
		true,
4163
		options);
4164
}
4165
// Bug 349326 - [1.7] new warning for missing try-with-resources
4166
// various non-problems
4167
public void test056l() {
4168
	Map options = getCompilerOptions();
4169
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4170
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4171
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4172
	this.runNegativeTest(
4173
		new String[] {
4174
			"X.java",
4175
			"import java.io.File;\n" +
4176
			"import java.io.FileReader;\n" +
4177
			"import java.io.IOException;\n" +
4178
			"public class X {\n" +
4179
			"    X(FileReader r0) {}\n" + // don't complain against argument
4180
			"    FileReader getReader() { return null; }\n" +
4181
			"    void foo(FileReader r1) throws IOException {\n" +
4182
			"        FileReader fileReader = getReader();\n" +
4183
			"        if (fileReader == null)\n" +
4184
			"            return;\n" + // don't complain, resource is actually null
4185
			"        FileReader r3 = getReader();\n" +
4186
			"        if (r3 == null)\n" +
4187
			"            r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null
4188
			"        try {\n" +
4189
			"            char[] in = new char[50];\n" +
4190
			"            fileReader.read(in);\n" +
4191
			"            r1.read(in);\n" +
4192
			"        } finally {\n" +
4193
			"            fileReader.close();\n" +
4194
			"            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
4195
			"        }\n" +
4196
			"    }\n" +
4197
			"    public static void main(String[] args) throws IOException {\n" +
4198
			"        FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" +
4199
			"        new X(r2).foo(new FileReader(new File(\"notthere\")));\n" +
4200
			"    }\n" +
4201
			"}\n"
4202
		},
4203
		"----------\n" + 
4204
		"1. ERROR in X.java (at line 8)\n" + 
4205
		"	FileReader fileReader = getReader();\n" + 
4206
		"	           ^^^^^^^^^^\n" + 
4207
		"Resource \'fileReader\' should be managed by try-with-resource\n" + 
4208
		"----------\n" + 
4209
		"2. ERROR in X.java (at line 11)\n" + 
4210
		"	FileReader r3 = getReader();\n" + 
4211
		"	           ^^\n" + 
4212
		"Resource 'r3' should be managed by try-with-resource\n" +
4213
		"----------\n" + 
4214
		"3. ERROR in X.java (at line 24)\n" + 
4215
		"	FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + 
4216
		"	           ^^\n" + 
4217
		"Potential resource leak: 'r2' may not be closed\n" + 
4218
		"----------\n",
4219
		null,
4220
		true,
4221
		options);
4222
}
4223
// Bug 349326 - [1.7] new warning for missing try-with-resources
4224
// nested try with early exit
4225
public void test056m() {
4226
	Map options = getCompilerOptions();
4227
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4228
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4229
	this.runConformTest(
4230
		new String[] {
4231
			"X.java",
4232
			"import java.io.File;\n" +
4233
			"import java.io.FileReader;\n" +
4234
			"import java.io.IOException;\n" +
4235
			"public class X {\n" +
4236
			"    void foo() {\n" +
4237
			"        File file = new File(\"somefile\");" +
4238
			"        try {\n" +
4239
			"            FileReader fileReader = new FileReader(file);\n" +
4240
			"            try {\n" +
4241
			"                char[] in = new char[50];\n" +
4242
			"                if (fileReader.read(in)==0)\n" +
4243
			"                    return;\n" +
4244
			"            } finally {\n" +
4245
			"		         fileReader.close();\n" +
4246
			"            }\n" +
4247
			"        } catch (IOException e) {\n" +
4248
			"            System.out.println(\"caught\");\n" +
4249
			"        }\n" +
4250
			"    }\n" +
4251
			"    public static void main(String[] args) {\n" +
4252
			"        new X().foo();\n" +
4253
			"    }\n" +
4254
			"}\n"
4255
		},
4256
		"caught", /*output*/
4257
		null/*classLibs*/,
4258
		true/*shouldFlush*/,
4259
		null/*vmargs*/,
4260
		options,
4261
		null/*requestor*/);
4262
}
4263
// Bug 349326 - [1.7] new warning for missing try-with-resources
4264
// nested try should not interfere with earlier analysis.
4265
public void test056n() {
4266
	Map options = getCompilerOptions();
4267
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4268
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4269
	this.runConformTest(
4270
		new String[] {
4271
			"X.java",
4272
			"import java.io.File;\n" +
4273
			"import java.io.FileReader;\n" +
4274
			"import java.io.IOException;\n" +
4275
			"import java.io.FileNotFoundException;\n" +
4276
			"public class X {\n" +
4277
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4278
			"		FileReader fr1 = new FileReader(someFile);\n" + 
4279
			"		try {\n" + 
4280
			"			fr1.read(buf);\n" + 
4281
			"		} finally {\n" + 
4282
			"			fr1.close();\n" + 
4283
			"		}\n" + 
4284
			"		try {\n" + 
4285
			"			FileReader fr3 = new FileReader(someFile);\n" + 
4286
			"			try {\n" + 
4287
			"			} finally {\n" + 
4288
			"				fr3.close();\n" + 
4289
			"			}\n" + 
4290
			"		} catch (IOException e) {\n" + 
4291
			"		}\n" + 
4292
			"	 }\n" +
4293
			"    public static void main(String[] args) throws IOException {\n" +
4294
			"        try {\n" +
4295
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4296
			"        } catch (FileNotFoundException e) {\n" +
4297
			"            System.out.println(\"caught\");\n" +
4298
			"        }\n" +
4299
			"    }\n" +
4300
			"}\n"
4301
		},
4302
		"caught", /*output*/
4303
		null/*classLibs*/,
4304
		true/*shouldFlush*/,
4305
		null/*vmargs*/,
4306
		options,
4307
		null/*requestor*/);
4308
}
4309
// Bug 349326 - [1.7] new warning for missing try-with-resources
4310
// if close is guarded by null check this should still be recognized as definitely closed
4311
public void test056o() {
4312
	Map options = getCompilerOptions();
4313
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4314
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4315
	this.runConformTest(
4316
		new String[] {
4317
			"X.java",
4318
			"import java.io.File;\n" +
4319
			"import java.io.FileReader;\n" +
4320
			"import java.io.IOException;\n" +
4321
			"import java.io.FileNotFoundException;\n" +
4322
			"public class X {\n" +
4323
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4324
			"		FileReader fr1 = null;\n" + 
4325
			"		try {\n" +
4326
			"           fr1 = new FileReader(someFile);" + 
4327
			"			fr1.read(buf);\n" + 
4328
			"		} finally {\n" + 
4329
			"			if (fr1 != null)\n" +
4330
			"               try {\n" +
4331
			"                   fr1.close();\n" +
4332
			"               } catch (IOException e) { /*do nothing*/ }\n" + 
4333
			"		}\n" + 
4334
			"	 }\n" +
4335
			"    public static void main(String[] args) throws IOException {\n" +
4336
			"        try {\n" +
4337
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4338
			"        } catch (FileNotFoundException e) {\n" +
4339
			"            System.out.println(\"caught\");\n" +
4340
			"        }\n" +
4341
			"    }\n" +
4342
			"}\n"
4343
		},
4344
		"caught", /*output*/
4345
		null/*classLibs*/,
4346
		true/*shouldFlush*/,
4347
		null/*vmargs*/,
4348
		options,
4349
		null/*requestor*/);
4350
}
4351
// Bug 349326 - [1.7] new warning for missing try-with-resources
4352
// a method uses an AutoCloseable without ever closing it, type from a type variable
4353
public void test056p() {
4354
	Map options = getCompilerOptions();
4355
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4356
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
4357
	this.runNegativeTest(
4358
		new String[] {
4359
			"X.java",
4360
			"import java.io.File;\n" +
4361
			"import java.io.FileReader;\n" +
4362
			"import java.io.Reader;\n" +
4363
			"import java.io.IOException;\n" +
4364
			"public abstract class X <T extends Reader> {\n" +
4365
			"    void foo() throws IOException {\n" +
4366
			"        File file = new File(\"somefile\");\n" +
4367
			"        T fileReader = newReader(file);\n" +
4368
			"        char[] in = new char[50];\n" +
4369
			"        fileReader.read(in);\n" +
4370
			"    }\n" +
4371
			"    abstract T newReader(File file) throws IOException;\n" +
4372
			"    public static void main(String[] args) throws IOException {\n" +
4373
			"        new X<FileReader>() {\n" +
4374
			"            FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" +
4375
			"        }.foo();\n" +
4376
			"    }\n" +
4377
			"}\n"
4378
		},
4379
		"----------\n" + 
4380
		"1. ERROR in X.java (at line 8)\n" + 
4381
		"	T fileReader = newReader(file);\n" + 
4382
		"	  ^^^^^^^^^^\n" + 
4383
		"Resource leak: 'fileReader' is never closed\n" +
4384
		"----------\n",
4385
		null,
4386
		true,
4387
		options);
4388
}
4389
// Bug 349326 - [1.7] new warning for missing try-with-resources
4390
// closed in dead code
4391
public void test056q() {
4392
	Map options = getCompilerOptions();
4393
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4394
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4395
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4396
	this.runNegativeTest(
4397
		new String[] {
4398
			"X.java",
4399
			"import java.io.File;\n" +
4400
			"import java.io.FileReader;\n" +
4401
			"import java.io.IOException;\n" +
4402
			"public class X {\n" +
4403
			"    void foo() throws IOException {\n" +
4404
			"        File file = new File(\"somefile\");\n" +
4405
			"        FileReader fileReader = new FileReader(file);\n" +
4406
			"        char[] in = new char[50];\n" +
4407
			"        fileReader.read(in);\n" +
4408
			"        if (2*2 == 4)\n" +
4409
			"        	return;\n" +
4410
			"        fileReader.close();\n" +
4411
			"    }\n" +
4412
			"    public static void main(String[] args) throws IOException {\n" +
4413
			"        new X().foo();\n" +
4414
			"    }\n" +
4415
			"}\n"
4416
		},
4417
		"----------\n" + 
4418
		"1. ERROR in X.java (at line 7)\n" + 
4419
		"	FileReader fileReader = new FileReader(file);\n" + 
4420
		"	           ^^^^^^^^^^\n" + 
4421
		"Resource leak: \'fileReader\' is never closed\n" + 
4422
		"----------\n" + 
4423
		"2. WARNING in X.java (at line 10)\n" + 
4424
		"	if (2*2 == 4)\n" + 
4425
		"	    ^^^^^^^^\n" + 
4426
		"Comparing identical expressions\n" + 
4427
		"----------\n" + 
4428
		"3. WARNING in X.java (at line 12)\n" + 
4429
		"	fileReader.close();\n" + 
4430
		"	^^^^^^^^^^^^^^^^^^\n" + 
4431
		"Dead code\n" + 
4432
		"----------\n",
4433
		null,
4434
		true,
4435
		options);
4436
}
4437
// Bug 349326 - [1.7] new warning for missing try-with-resources
4438
// closed in dead code
4439
public void test056r() {
4440
	Map options = getCompilerOptions();
4441
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4442
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4443
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4444
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4445
	this.runNegativeTest(
4446
		new String[] {
4447
			"X.java",
4448
			"import java.io.File;\n" +
4449
			"import java.io.FileReader;\n" +
4450
			"import java.io.IOException;\n" +
4451
			"public class X {\n" +
4452
			"    void foo() throws IOException {\n" +
4453
			"        File file = new File(\"somefile\");\n" +
4454
			"        FileReader fr = new FileReader(file);\n" +
4455
			"  		 Object b = null;\n" + 
4456
			"        fr.close();\n" + 
4457
			"        if (b != null) {\n" + 
4458
			"            fr = new FileReader(file);\n" + 
4459
			"            return;\n" + 
4460
			"        } else {\n" + 
4461
			"            System.out.print(42);\n" + 
4462
			"        }\n" + 
4463
			"        return;     // Should not complain about fr\n" +
4464
			"    }\n" +
4465
			"    public static void main(String[] args) throws IOException {\n" +
4466
			"        new X().foo();\n" +
4467
			"    }\n" +
4468
			"}\n"
4469
		},
4470
		"----------\n" + 
4471
		"1. ERROR in X.java (at line 10)\n" + 
4472
		"	if (b != null) {\n" + 
4473
		"            fr = new FileReader(file);\n" + 
4474
		"            return;\n" + 
4475
		"        } else {\n" + 
4476
		"	               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4477
		"Dead code\n" + 
4478
		"----------\n" + 
4479
		"2. WARNING in X.java (at line 13)\n" + 
4480
		"	} else {\n" + 
4481
		"            System.out.print(42);\n" + 
4482
		"        }\n" + 
4483
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4484
		"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + 
4485
		"----------\n",
4486
		null,
4487
		true,
4488
		options);
4489
}
4490
// Bug 349326 - [1.7] new warning for missing try-with-resources
4491
// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation
4492
public void test056s() {
4493
	Map options = getCompilerOptions();
4494
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4495
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4496
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4497
	this.runNegativeTest(
4498
		new String[] {
4499
			"X.java",
4500
			"import java.io.File;\n" + 
4501
			"import java.io.FileReader;\n" + 
4502
			"import java.io.IOException;\n" + 
4503
			"public class X {\n" + 
4504
			"    void foo() throws IOException {\n" + 
4505
			"        File file = new File(\"somefile\");\n" + 
4506
			"        try (FileReader fileReader = new FileReader(file);) {\n" + 
4507
			"            char[] in = new char[50];\n" + 
4508
			"            fileReader.read(in);\n" + 
4509
			"            fileReader = new FileReader(file);  // debug here\n" + 
4510
			"            fileReader.read(in);\n" + 
4511
			"        }\n" + 
4512
			"    }\n" +
4513
			"    public static void main(String[] args) throws IOException {\n" + 
4514
			"        new X().foo();\n" + 
4515
			"    }\n" + 
4516
			"}\n"
4517
		},
4518
		"----------\n" + 
4519
		"1. ERROR in X.java (at line 10)\n" + 
4520
		"	fileReader = new FileReader(file);  // debug here\n" + 
4521
		"	^^^^^^^^^^\n" + 
4522
		"The resource fileReader of a try-with-resources statement cannot be assigned\n" + 
4523
		"----------\n",
4524
		null,
4525
		true,
4526
		options);
4527
}
4528
// Bug 349326 - [1.7] new warning for missing try-with-resources
4529
// resource is closed, dead code follows
4530
public void test056t() {
4531
	Map options = getCompilerOptions();
4532
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4533
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4534
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4535
	this.runNegativeTest(
4536
		new String[] {
4537
			"X.java",
4538
			"import java.io.FileReader;\n" + 
4539
			"import java.io.IOException;\n" + 
4540
			"public class X {\n" + 
4541
			"    void foo31() throws IOException {\n" + 
4542
			"        FileReader reader = new FileReader(\"file\"); //warning\n" +
4543
			"        if (reader != null) {\n" + 
4544
			"            reader.close();\n" + 
4545
			"        } else {\n" + 
4546
			"            // nop\n" + 
4547
			"        }\n" + 
4548
			"    }\n" + 
4549
			"    public static void main(String[] args) throws IOException {\n" + 
4550
			"        new X().foo31();\n" + 
4551
			"    }\n" + 
4552
			"}\n"
4553
		},
4554
		"----------\n" + 
4555
		"1. ERROR in X.java (at line 8)\n" + 
4556
		"	} else {\n" + 
4557
		"            // nop\n" + 
4558
		"        }\n" + 
4559
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4560
		"Dead code\n" + 
4561
		"----------\n",
4562
		null,
4563
		true,
4564
		options);
4565
}
4566
// Bug 349326 - [1.7] new warning for missing try-with-resources
4567
// resource is reassigned within t-w-r with different resource
4568
// disabled due to Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
4569
public void _test056u() {
4570
	Map options = getCompilerOptions();
4571
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4572
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4573
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4574
	this.runNegativeTest(
4575
		new String[] {
4576
			"X.java",
4577
			"import java.io.FileReader;\n" + 
4578
			"public class X {\n" + 
4579
			"    void foo() throws Exception {\n" + 
4580
			"        FileReader reader1 = new FileReader(\"file1\");\n" + 
4581
			"        FileReader reader2 = new FileReader(\"file2\");\n" + 
4582
			"        reader2 = reader1;// warning 1\n" + 
4583
			"        try (FileReader reader3 = new FileReader(\"file3\")) {\n" + 
4584
			"            int ch;\n" + 
4585
			"            while ((ch = reader2.read()) != -1) {\n" + 
4586
			"                System.out.println(ch);\n" + 
4587
			"                reader1.read();\n" + 
4588
			"            }\n" + 
4589
			"            reader2 = reader1;// warning 2\n" + 
4590
			"            reader2 = reader1;// warning 3\n" + 
4591
			"        } finally {\n" + 
4592
			"            if (reader2 != null) {\n" + 
4593
			"                reader2.close();\n" + 
4594
			"            } else {\n" + 
4595
			"                System.out.println();\n" + 
4596
			"            }\n" + 
4597
			"        }\n" + 
4598
			"    }\n" + 
4599
			"}\n"
4600
		},
4601
		"----------\n" + 
4602
		"1. ERROR in X.java (at line 4)\n" + 
4603
		"	FileReader reader1 = new FileReader(\"file1\");\n" + 
4604
		"	           ^^^^^^^\n" + 
4605
		"Resource leak: \'reader1\' is never closed\n" + 
4606
		"----------\n" + 
4607
		"2. ERROR in X.java (at line 4)\n" + 
4608
		"	reader2 = reader1;// warning 1\n" + 
4609
		"	^^^^^^^^^^^^^^^^^\n" + 
4610
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4611
		"----------\n" + 
4612
		"3. ERROR in X.java (at line 13)\n" + 
4613
		"	reader2 = reader1;// warning 2\n" + 
4614
		"	^^^^^^^^^^^^^^^^^\n" + 
4615
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4616
		"----------\n" + 
4617
		"4. ERROR in X.java (at line 14)\n" + 
4618
		"	reader2 = reader1;// warning 3\n" + 
4619
		"	^^^^^^^^^^^^^^^^^\n" + 
4620
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4621
		"----------\n",
4622
		null,
4623
		true,
4624
		options);
4625
}
4626
// Bug 349326 - [1.7] new warning for missing try-with-resources
4627
// pb reported in https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326#c70
4628
public void test056v() {
4629
	Map options = getCompilerOptions();
4630
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4631
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4632
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4633
	this.runNegativeTest(
4634
		new String[] {
4635
			"X.java",
4636
			"import java.io.FileReader;\n" + 
4637
			"public class X {\n" + 
4638
			"    boolean foo1() throws Exception {\n" + 
4639
			"        FileReader reader = new FileReader(\"file\");\n" + 
4640
			"        try {\n" + 
4641
			"            int ch;\n" + 
4642
			"            while ((ch = reader.read()) != -1) {\n" + 
4643
			"                System.out.println(ch);\n" + 
4644
			"                reader.read();\n" + 
4645
			"            }\n" + 
4646
			"            if (ch > 10) {\n" + 
4647
			"                return true;\n" + 
4648
			"            }\n" + 
4649
			"            return false;\n" + // return while resource from enclosing scope remains unclosed
4650
			"        } finally {\n" + 
4651
			"        }\n" + 
4652
			"    }\n" + 
4653
			"    void foo2() throws Exception {\n" + 
4654
			"        FileReader reader2 = new FileReader(\"file\");\n" + 
4655
			"        try {\n" + 
4656
			"            int ch;\n" + 
4657
			"            while ((ch = reader2.read()) != -1) {\n" + 
4658
			"                System.out.println(ch);\n" + 
4659
			"                reader2.read();\n" + 
4660
			"            }\n" + 
4661
			"            if (ch > 10) {\n" + 
4662
			"                return;\n" + // potential leak
4663
			"            }\n" + 
4664
			"        } finally {\n" + 
4665
			"        }\n" +
4666
			"        reader2.close();\n" + // due to this close we don't say "never closed"
4667
			"    }\n" + 
4668
			"}\n"
4669
		},
4670
		"----------\n" + 
4671
		"1. ERROR in X.java (at line 4)\n" + 
4672
		"	FileReader reader = new FileReader(\"file\");\n" + 
4673
		"	           ^^^^^^\n" + 
4674
		"Resource leak: \'reader\' is never closed\n" + 
4675
		"----------\n" + 
4676
		"2. ERROR in X.java (at line 27)\n" + 
4677
		"	return;\n" + 
4678
		"	^^^^^^^\n" + 
4679
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4680
		"----------\n",
4681
		null,
4682
		true,
4683
		options);
4684
}
4685
// Bug 349326 - [1.7] new warning for missing try-with-resources
4686
// end of method is dead end, but before we have both a close() and an early return
4687
public void test056w() {
4688
	Map options = getCompilerOptions();
4689
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4690
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4691
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4692
	this.runNegativeTest(
4693
		new String[] {
4694
			"X.java",
4695
			"import java.io.FileReader;\n" + 
4696
			"public class X {\n" + 
4697
			"    boolean foo1() throws Exception {\n" + 
4698
			"        FileReader reader = new FileReader(\"file\");\n" + 
4699
			"        try {\n" + 
4700
			"            int ch;\n" + 
4701
			"            while ((ch = reader.read()) != -1) {\n" + 
4702
			"                System.out.println(ch);\n" + 
4703
			"                reader.read();\n" + 
4704
			"            }\n" + 
4705
			"            if (ch > 10) {\n" +
4706
			"				 reader.close();\n" + 
4707
			"                return true;\n" + 
4708
			"            }\n" + 
4709
			"            return false;\n" + 
4710
			"        } finally {\n" + 
4711
			"        }\n" + 
4712
			"    }\n" + 
4713
			"}\n"
4714
		},
4715
		"----------\n" + 
4716
		"1. ERROR in X.java (at line 15)\n" + 
4717
		"	return false;\n" + 
4718
		"	^^^^^^^^^^^^^\n" + 
4719
		"Resource leak: \'reader\' is not closed at this location\n" + 
4720
		"----------\n",
4721
		null,
4722
		true,
4723
		options);
4724
}
4725
// Bug 349326 - [1.7] new warning for missing try-with-resources
4726
// different early exits, if no close seen report as definitely unclosed
4727
public void test056x() {
4728
	Map options = getCompilerOptions();
4729
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4730
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4731
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4732
	this.runNegativeTest(
4733
		new String[] {
4734
			"X.java",
4735
			"import java.io.FileReader;\n" +
4736
			"public class X {\n" +
4737
			"    void foo31(boolean b) throws Exception {\n" +
4738
			"        FileReader reader = new FileReader(\"file\");\n" +
4739
			"        if (b) {\n" +
4740
			"            reader.close();\n" +
4741
			"        } else {\n" +
4742
			"            return; // warning\n" +
4743
			"        }\n" +
4744
			"    }\n" +
4745
			"    void foo32(boolean b) throws Exception {\n" +
4746
			"        FileReader reader = new FileReader(\"file\"); // warn here\n" +
4747
			"        return;\n" +
4748
			"    }\n" +
4749
			"}\n"
4750
		},
4751
		"----------\n" +
4752
		"1. ERROR in X.java (at line 8)\n" +
4753
		"	return; // warning\n" +
4754
		"	^^^^^^^\n" +
4755
		"Resource leak: \'reader\' is not closed at this location\n" +
4756
		"----------\n" +
4757
		"2. ERROR in X.java (at line 12)\n" +
4758
		"	FileReader reader = new FileReader(\"file\"); // warn here\n" +
4759
		"	           ^^^^^^\n" +
4760
		"Resource leak: \'reader\' is never closed\n" +
4761
		"----------\n",
4762
		null,
4763
		true,
4764
		options);
4765
}
4766
// Bug 349326 - [1.7] new warning for missing try-with-resources
4767
// nested method passes the resource to outside code
4768
public void test056y() {
4769
	Map options = getCompilerOptions();
4770
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4771
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4772
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4773
	this.runNegativeTest(
4774
		new String[] {
4775
			"X.java",
4776
			"import java.io.FileReader;\n" +
4777
			"public class X {\n" +
4778
			"    void foo31(boolean b) throws Exception {\n" +
4779
			"        final FileReader reader31 = new FileReader(\"file\");\n" +
4780
			"        new Runnable() {\n" +
4781
			"            public void run() {\n" +
4782
			"                foo18(reader31);\n" +
4783
			"            }\n" +
4784
			"        }.run();\n" +
4785
			"    }\n" +
4786
			"    void foo18(FileReader r18) {\n" +
4787
			"        // could theoretically close r18;\n" +
4788
			"    }\n" +
4789
			"    abstract class ResourceProvider {\n" +
4790
			"        abstract FileReader provide();" +
4791
			"    }\n" +
4792
			"    ResourceProvider provider;" +
4793
			"    void foo23() throws Exception {\n" +
4794
			"        final FileReader reader23 = new FileReader(\"file\");\n" +
4795
			"        provider = new ResourceProvider() {\n" +
4796
			"            public FileReader provide() {\n" +
4797
			"                return reader23;\n" +
4798
			"            }\n" +
4799
			"        };\n" +
4800
			"    }\n" +
4801
			"}\n"
4802
		},
4803
		"----------\n" + 
4804
		"1. WARNING in X.java (at line 4)\n" + 
4805
		"	final FileReader reader31 = new FileReader(\"file\");\n" + 
4806
		"	                 ^^^^^^^^\n" + 
4807
		"Potential resource leak: \'reader31\' may not be closed\n" + 
4808
		"----------\n" + 
4809
		"2. WARNING in X.java (at line 17)\n" + 
4810
		"	final FileReader reader23 = new FileReader(\"file\");\n" + 
4811
		"	                 ^^^^^^^^\n" + 
4812
		"Potential resource leak: \'reader23\' may not be closed\n" + 
4813
		"----------\n",
4814
		null,
4815
		true,
4816
		options);
4817
}
4818
// Bug 349326 - [1.7] new warning for missing try-with-resources
4819
// resource assigned to second local and is (potentially) closed on the latter
4820
public void test056z() {
4821
	Map options = getCompilerOptions();
4822
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4823
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4824
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4825
	this.runNegativeTest(
4826
		new String[] {
4827
			"X.java",
4828
			"import java.io.FileReader;\n" +
4829
			"public class X {\n" +
4830
			"    void foo17() throws Exception {\n" +
4831
			"        FileReader reader17 = new FileReader(\"file\");\n" +
4832
			"        final FileReader readerCopy = reader17;\n" +
4833
			"        readerCopy.close();\n" +
4834
			"    }\n" +
4835
			"    void foo17a() throws Exception {\n" +
4836
			"        FileReader reader17a = new FileReader(\"file\");\n" +
4837
			"        FileReader readerCopya;" +
4838
			"		 readerCopya = reader17a;\n" +
4839
			"        bar(readerCopya);\n" + // potentially closes
4840
			"    }\n" +
4841
			"    void bar(FileReader r) {}\n" +
4842
			"}\n"
4843
		},
4844
		"----------\n" + 
4845
		"1. ERROR in X.java (at line 9)\n" + 
4846
		"	FileReader reader17a = new FileReader(\"file\");\n" + 
4847
		"	           ^^^^^^^^^\n" + 
4848
		"Potential resource leak: \'reader17a\' may not be closed\n" + 
4849
		"----------\n",
4850
		null,
4851
		true,
4852
		options);
4853
}
4854
// Bug 349326 - [1.7] new warning for missing try-with-resources
4855
// multiple early exists from nested scopes (always closed) 
4856
public void test056zz() {
4857
	Map options = getCompilerOptions();
4858
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4859
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4860
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
4861
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4862
	this.runNegativeTest(
4863
		new String[] {
4864
			"X.java",
4865
			"import java.io.FileReader;\n" +
4866
			"public class X {\n" +
4867
			"    void foo16() throws Exception {\n" +
4868
			"        FileReader reader16 = new FileReader(\"file\");\n" +
4869
			"        try {\n" +
4870
			"            reader16.close();\n " +
4871
			"            return;\n" +
4872
			"        } catch (RuntimeException re) {\n" +
4873
			"            return;\n" +
4874
			"        } catch (Error e) {\n" +
4875
			"            return;\n" +
4876
			"        } finally {\n" +
4877
			"            reader16.close();\n " +
4878
			"        }\n" +
4879
			"    }\n" +
4880
			"}\n"
4881
		},
4882
		"----------\n" + 
4883
		"1. ERROR in X.java (at line 4)\n" + 
4884
		"	FileReader reader16 = new FileReader(\"file\");\n" + 
4885
		"	           ^^^^^^^^\n" + 
4886
		"Resource \'reader16\' should be managed by try-with-resource\n" + 
4887
		"----------\n",
4888
		null,
4889
		true,
4890
		options);
4891
}
4892
// Bug 349326 - [1.7] new warning for missing try-with-resources
4893
// multiple early exists from nested scopes (never closed) 
4894
public void test056zzz() {
4895
	Map options = getCompilerOptions();
4896
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4897
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4898
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR);
4899
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4900
	this.runNegativeTest(
4901
		new String[] {
4902
			"X.java",
4903
			"import java.io.FileReader;\n" +
4904
			"public class X {\n" +
4905
			"    void foo16() throws Exception {\n" +
4906
			"        FileReader reader16 = new FileReader(\"file\");\n" +
4907
			"        try {\n" +
4908
			"            return;\n" +
4909
			"        } catch (RuntimeException re) {\n" +
4910
			"            return;\n" +
4911
			"        } catch (Error e) {\n" +
4912
			"            return;\n" +
4913
			"        } finally {\n" +
4914
			"            System.out.println();\n " +
4915
			"        }\n" +
4916
			"    }\n" +
4917
			"}\n"
4918
		},
4919
		"----------\n" + 
4920
		"1. ERROR in X.java (at line 4)\n" + 
4921
		"	FileReader reader16 = new FileReader(\"file\");\n" + 
4922
		"	           ^^^^^^^^\n" + 
4923
		"Resource leak: \'reader16\' is never closed\n" + 
4924
		"----------\n",
4925
		null,
4926
		true,
4927
		options);
4928
}
3435
public static Class testClass() {
4929
public static Class testClass() {
3436
	return TryWithResourcesStatementTest.class;
4930
	return TryWithResourcesStatementTest.class;
3437
}
4931
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java (-1 / +16 lines)
Lines 116-122 Link Here
116
 *		Benjamin Muskalla - added the following constants
116
 *		Benjamin Muskalla - added the following constants
117
 *									MissingSynchronizedModifierInInheritedMethod
117
 *									MissingSynchronizedModifierInInheritedMethod
118
 *		Stephan Herrmann  - added the following constants
118
 *		Stephan Herrmann  - added the following constants
119
 *									UnusedObjectAllocation									
119
 *									UnusedObjectAllocation
120
 *									PotentiallyUnclosedCloseable
121
 *									PotentiallyUnclosedCloseableAtExit
122
 *									UnclosedCloseable
123
 *									UnclosedCloseableAtExit
124
 *									ExplicitlyClosedAutoCloseable
120
 *******************************************************************************/
125
 *******************************************************************************/
121
package org.eclipse.jdt.core.compiler;
126
package org.eclipse.jdt.core.compiler;
122
127
Lines 1394-1399 Link Here
1394
	int DiamondNotBelow17 =  TypeRelated + 883;
1399
	int DiamondNotBelow17 =  TypeRelated + 883;
1395
	/** @since 3.7.1 */
1400
	/** @since 3.7.1 */
1396
	int RedundantSpecificationOfTypeArguments = TypeRelated + 884;
1401
	int RedundantSpecificationOfTypeArguments = TypeRelated + 884;
1402
	/** @since 3.8 */
1403
	int PotentiallyUnclosedCloseable = Internal + 885;
1404
	/** @since 3.8 */
1405
	int PotentiallyUnclosedCloseableAtExit = Internal + 886;
1406
	/** @since 3.8 */
1407
	int UnclosedCloseable = Internal + 887;
1408
	/** @since 3.8 */
1409
	int UnclosedCloseableAtExit = Internal + 888;
1410
	/** @since 3.8 */
1411
	int ExplicitlyClosedAutoCloseable = Internal + 889;
1397
	/**
1412
	/**
1398
	 * External problems -- These are problems defined by other plugins
1413
	 * External problems -- These are problems defined by other plugins
1399
	 */
1414
	 */
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java (+3 lines)
Lines 10-15 Link Here
10
 *     Stephan Herrmann - Contributions for 
10
 *     Stephan Herrmann - Contributions for 
11
 *     						bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
11
 *     						bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
12
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
13
 *     						bug 349326 - [1.7] new warning for missing try-with-resources
13
 *******************************************************************************/
14
 *******************************************************************************/
14
package org.eclipse.jdt.internal.compiler.ast;
15
package org.eclipse.jdt.internal.compiler.ast;
15
16
Lines 42-47 Link Here
42
	// process arguments
43
	// process arguments
43
	if (this.arguments != null) {
44
	if (this.arguments != null) {
44
		for (int i = 0, count = this.arguments.length; i < count; i++) {
45
		for (int i = 0, count = this.arguments.length; i < count; i++) {
46
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
47
			flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo);
45
			flowInfo =
48
			flowInfo =
46
				this.arguments[i]
49
				this.arguments[i]
47
					.analyseCode(currentScope, flowContext, flowInfo)
50
					.analyseCode(currentScope, flowContext, flowInfo)
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (+11 lines)
Lines 12-17 Link Here
12
 * 							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 * 							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
13
 * 							bug 292478 - Report potentially null across variable assignment
13
 * 							bug 292478 - Report potentially null across variable assignment
14
 *     						bug 335093 - [compiler][null] minimal hook for future null annotation support
14
 *     						bug 335093 - [compiler][null] minimal hook for future null annotation support
15
 *     						bug 349326 - [1.7] new warning for missing try-with-resources
15
 *******************************************************************************/
16
 *******************************************************************************/
16
package org.eclipse.jdt.internal.compiler.ast;
17
package org.eclipse.jdt.internal.compiler.ast;
17
18
Lines 47-52 Link Here
47
	flowInfo = ((Reference) this.lhs)
48
	flowInfo = ((Reference) this.lhs)
48
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
49
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
49
		.unconditionalInits();
50
		.unconditionalInits();
51
	if (local != null) {
52
		LocalVariableBinding previousTrackerBinding = null;
53
		if (local.closeTracker != null) {
54
			// Assigning to a variable already holding an AutoCloseable, has it been closed before?
55
			previousTrackerBinding = local.closeTracker.binding;
56
			if (!flowInfo.isDefinitelyNull(local)) // only if previous value may be non-null
57
				local.closeTracker.recordErrorLocation(this, flowInfo.nullStatus(previousTrackerBinding));
58
		}
59
		FakedTrackingVariable.handleResourceAssignment(flowInfo, this, this.expression, local, previousTrackerBinding);
60
	}
50
	int nullStatus = this.expression.nullStatus(flowInfo);
61
	int nullStatus = this.expression.nullStatus(flowInfo);
51
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
62
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
52
		if (nullStatus == FlowInfo.NULL) {
63
		if (nullStatus == FlowInfo.NULL) {
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java (-2 / +5 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 32-41 Link Here
32
	int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
33
	int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
33
	for (int i = 0, max = this.statements.length; i < max; i++) {
34
	for (int i = 0, max = this.statements.length; i < max; i++) {
34
		Statement stat = this.statements[i];
35
		Statement stat = this.statements[i];
35
		if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
36
		if ((complaintLevel = stat.complainIfUnreachable(flowInfo, flowContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
36
			flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
37
			flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
37
		}
38
		}
38
	}
39
	}
40
	if (this.explicitDeclarations > 0) // if block has its own scope analyze tracking vars now:
41
		this.scope.checkUnclosedCloseables(flowInfo, flowContext, null);
39
	return flowInfo;
42
	return flowInfo;
40
}
43
}
41
/**
44
/**
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java (-2 / +3 lines)
Lines 12-17 Link Here
12
 *     						bug 292478 - Report potentially null across variable assignment
12
 *     						bug 292478 - Report potentially null across variable assignment
13
 * 							bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
13
 * 							bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
14
 * 							bug 354554 - [null] conditional with redundant condition yields weak error message
14
 * 							bug 354554 - [null] conditional with redundant condition yields weak error message
15
 *     						bug 349326 - [1.7] new warning for missing try-with-resources
15
 *******************************************************************************/
16
 *******************************************************************************/
16
package org.eclipse.jdt.internal.compiler.ast;
17
package org.eclipse.jdt.internal.compiler.ast;
17
18
Lines 65-71 Link Here
65
				trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
66
				trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
66
			}
67
			}
67
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
68
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
68
				this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel);
69
				this.valueIfTrue.complainIfUnreachable(trueFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
69
			}
70
			}
70
		}
71
		}
71
		this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo);
72
		this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo);
Lines 78-84 Link Here
78
				falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
79
				falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
79
			}
80
			}
80
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
81
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
81
				this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel);
82
				this.valueIfFalse.complainIfUnreachable(falseFlowInfo, flowContext, currentScope, initialComplaintLevel, true);
82
			}
83
			}
83
		}
84
		}
84
		this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo);
85
		this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo);
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java (-2 / +4 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for Bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 151-157 Link Here
151
			int complaintLevel = (nonStaticFieldInfoReachMode & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
153
			int complaintLevel = (nonStaticFieldInfoReachMode & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
152
			for (int i = 0, count = this.statements.length; i < count; i++) {
154
			for (int i = 0, count = this.statements.length; i < count; i++) {
153
				Statement stat = this.statements[i];
155
				Statement stat = this.statements[i];
154
				if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
156
				if ((complaintLevel = stat.complainIfUnreachable(flowInfo, constructorContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
155
					flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo);
157
					flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo);
156
				}
158
				}
157
			}
159
			}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java (-3 / +4 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 29-40 Link Here
29
	}
30
	}
30
31
31
	// Report an error if necessary
32
	// Report an error if necessary
32
	public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int complaintLevel) {
33
	public int complainIfUnreachable(FlowInfo flowInfo, FlowContext flowContext, BlockScope scope, int complaintLevel, boolean endOfBlock) {
33
		// before 1.4, empty statements are tolerated anywhere
34
		// before 1.4, empty statements are tolerated anywhere
34
		if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
35
		if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
35
			return complaintLevel;
36
			return complaintLevel;
36
		}
37
		}
37
		return super.complainIfUnreachable(flowInfo, scope, complaintLevel);
38
		return super.complainIfUnreachable(flowInfo, flowContext, scope, complaintLevel, endOfBlock);
38
	}
39
	}
39
40
40
	public void generateCode(BlockScope currentScope, CodeStream codeStream){
41
	public void generateCode(BlockScope currentScope, CodeStream codeStream){
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java (+235 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 GK Software AG and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Stephan Herrmann - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
13
import java.util.HashMap;
14
import java.util.Iterator;
15
import java.util.Map;
16
import java.util.Map.Entry;
17
18
import org.eclipse.jdt.core.compiler.CharOperation;
19
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
21
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
22
import org.eclipse.jdt.internal.compiler.impl.Constant;
23
import org.eclipse.jdt.internal.compiler.lookup.Binding;
24
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
25
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
27
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
28
import org.eclipse.jdt.internal.compiler.lookup.Scope;
29
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
30
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
31
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
32
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
33
34
/**
35
 * A faked local variable declaration used for keeping track of data flows of a
36
 * special variable. Certain events will be recorded by changing the null info
37
 * for this variable.
38
 * 
39
 * See bug 349326 - [1.7] new warning for missing try-with-resources
40
 */
41
public class FakedTrackingVariable extends LocalDeclaration {
42
43
	private static final int CLOSE_SEEN = 1;
44
	private static final int PASSED_TO_OUTSIDE = 2;
45
	// If close() is invoked from a nested method (inside a local type) report remaining problems only as potential:
46
	private static final int CLOSED_IN_NESTED_METHOD = 4;
47
	private static final int REPORTED = 8;
48
	
49
	/**
50
	 * Bitset of {@link #CLOSE_SEEN}, {@link #PASSED_TO_OUTSIDE} and {@link #CLOSED_IN_NESTED_METHOD}.
51
	 */
52
	private int globalClosingState = 0;
53
54
	MethodScope methodScope; // designates the method declaring this variable
55
	
56
	public LocalVariableBinding originalBinding; // the real local being tracked
57
	
58
	HashMap recordedLocations; // initially null, ASTNode -> Integer 
59
60
61
	public FakedTrackingVariable(LocalVariableBinding original, Statement location) {
62
		super(original.name, location.sourceStart, location.sourceEnd);
63
		this.type = new SingleTypeReference(
64
				TypeConstants.OBJECT,
65
				((long)this.sourceStart <<32)+this.sourceEnd);
66
		this.methodScope = original.declaringScope.methodScope();
67
		this.originalBinding = original;
68
		resolve(original.declaringScope);
69
	}
70
	
71
	public void generateCode(BlockScope currentScope, CodeStream codeStream)
72
	{ /* NOP - this variable is completely dummy, ie. for analysis only. */ }
73
74
	public void resolve (BlockScope scope) {
75
		// only need the binding, which is used as reference in FlowInfo methods.
76
		this.binding = new LocalVariableBinding(
77
				this.name,
78
				scope.getJavaLangObject(),  // dummy, just needs to be a reference type
79
				0,
80
				false);
81
		this.binding.setConstant(Constant.NotAConstant);
82
		this.binding.useFlag = LocalVariableBinding.USED;
83
		// use a free slot without assigning it:
84
		this.binding.id = scope.registerTrackingVariable(this);
85
	}
86
87
	/**
88
	 * If expression resolves to a local variable binding of type AutoCloseable,
89
	 * answer the variable that tracks closing of that local, creating it if needed.
90
	 * @param expression
91
	 * @return a new {@link FakedTrackingVariable} or null.
92
	 */
93
	public static FakedTrackingVariable getCloseTrackingVariable(Expression expression) {
94
		if (expression instanceof SingleNameReference) {
95
			SingleNameReference name = (SingleNameReference) expression;
96
			if (name.binding instanceof LocalVariableBinding) {
97
				LocalVariableBinding local = (LocalVariableBinding)name.binding;
98
				if (local.closeTracker != null)
99
					return local.closeTracker;
100
				if (local.isParameter() || !isAutoCloseable(expression.resolvedType))
101
					return null;
102
				// tracking var doesn't yet exist. This happens in finally block
103
				// which is analyzed before the corresponding try block
104
				Statement location = local.declaration;
105
				return local.closeTracker = new FakedTrackingVariable(local, location);
106
			}
107
		}
108
		return null;
109
	}
110
111
	/** if 'invocationSite' is a call to close() that has a registered tracking variable, answer that variable's binding. */
112
	public static LocalVariableBinding getTrackerForCloseCall(ASTNode invocationSite) {
113
		if (invocationSite instanceof MessageSend) {
114
			MessageSend send = (MessageSend) invocationSite;
115
			if (CharOperation.equals(TypeConstants.CLOSE, send.selector) && send.receiver instanceof SingleNameReference) {
116
				Binding receiverBinding = ((SingleNameReference)send.receiver).binding;
117
				if (receiverBinding instanceof LocalVariableBinding) {
118
					FakedTrackingVariable trackingVariable = ((LocalVariableBinding)receiverBinding).closeTracker;
119
					if (trackingVariable != null)
120
						return trackingVariable.binding;
121
				}
122
			}
123
		}
124
		return null;
125
	}
126
127
	/** 
128
	 * Check if the rhs of an assignment or local declaration is an (Auto)Closeable.
129
	 * If so create or re-use a tracking variable, and wire and initialize everything. 
130
	 */
131
	public static void handleResourceAssignment(FlowInfo flowInfo, Statement location, Expression rhs, LocalVariableBinding local,
132
				LocalVariableBinding previousTrackerBinding) 
133
	{
134
		if (isAutoCloseable(rhs.resolvedType)) {
135
			// new value is AutoCloseable, start tracking, possibly re-using existing tracker var:
136
	
137
			FakedTrackingVariable rhsTrackVar = getCloseTrackingVariable(rhs);
138
			if (rhsTrackVar != null) {								// 1. share tracking variable with RHS?
139
				local.closeTracker = rhsTrackVar;
140
				// keep null-status unchanged across this assignment
141
			} else if (previousTrackerBinding != null) {			// 2. re-use tracking variable from the LHS?
142
				// re-assigning from a fresh, mark as not-closed again:
143
				flowInfo.markAsDefinitelyNull(previousTrackerBinding);
144
			} else {												// 3. no re-use, create a fresh tracking variable:
145
				local.closeTracker = new FakedTrackingVariable(local, location);
146
				// a fresh resource, mark as not-closed:
147
				flowInfo.markAsDefinitelyNull(local.closeTracker.binding);
148
// TODO(stephan): this might be useful, but I could not find a test case for it: 
149
//				if (flowContext.initsOnFinally != null)
150
//					flowContext.initsOnFinally.markAsDefinitelyNonNull(trackerBinding);
151
			}
152
		}
153
	}
154
155
	/** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */
156
	public static boolean isAutoCloseable(TypeBinding typeBinding) {
157
		return typeBinding instanceof ReferenceBinding
158
			&& ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable);
159
	}
160
161
	/** Mark that this resource is closed locally. */
162
	public void markClose(FlowInfo flowInfo, FlowContext flowContext) {
163
		flowInfo.markAsDefinitelyNonNull(this.binding);
164
		this.globalClosingState |= CLOSE_SEEN;
165
//TODO(stephan): this might be useful, but I could not find a test case for it: 
166
//		if (flowContext.initsOnFinally != null)
167
//			flowContext.initsOnFinally.markAsDefinitelyNonNull(this.binding);		
168
	}
169
170
	/** Mark that this resource is closed from a nested method (inside a local class). */
171
	public void markClosedInNestedMethod() {
172
		this.globalClosingState |= CLOSED_IN_NESTED_METHOD;
173
	}
174
175
	/** 
176
	 * Mark that this resource is passed to some outside code
177
	 * (as argument to a method/ctor call or as a return value from the current method), 
178
	 * and thus should be considered as potentially closed.
179
	 */
180
	public static FlowInfo markPassedToOutside(BlockScope scope, Expression expression, FlowInfo flowInfo) {
181
		FakedTrackingVariable trackVar = getCloseTrackingVariable(expression);
182
		if (trackVar != null) {
183
			trackVar.globalClosingState |= PASSED_TO_OUTSIDE;
184
			if (scope.methodScope() != trackVar.methodScope)
185
				trackVar.globalClosingState |= CLOSED_IN_NESTED_METHOD;
186
			// insert info that the tracked resource *may* be closed (by the target method, i.e.)
187
			FlowInfo infoResourceIsClosed = flowInfo.copy();
188
			infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding);
189
			return FlowInfo.conditional(flowInfo, infoResourceIsClosed);
190
		}
191
		return flowInfo;
192
	}
193
	
194
	public void recordErrorLocation(ASTNode location, int nullStatus) {
195
		if (this.recordedLocations == null)
196
			this.recordedLocations = new HashMap();
197
		this.recordedLocations.put(location, new Integer(nullStatus));
198
	}
199
200
	public boolean reportRecordedErrors(Scope scope) {
201
		if (this.globalClosingState == 0) {
202
			reportError(scope.problemReporter(), null, FlowInfo.NULL);
203
			return true;
204
		}
205
		boolean hasReported = false;
206
		if (this.recordedLocations != null) {
207
			Iterator locations = this.recordedLocations.entrySet().iterator();
208
			while (locations.hasNext()) {
209
				Map.Entry entry = (Entry) locations.next();
210
				reportError(scope.problemReporter(), (ASTNode)entry.getKey(), ((Integer)entry.getValue()).intValue());
211
				hasReported = true;
212
			}
213
		}
214
		return hasReported;
215
	}
216
	
217
	public void reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) {
218
		if (nullStatus == FlowInfo.NULL) {
219
			if ((this.globalClosingState & CLOSED_IN_NESTED_METHOD) != 0)
220
				problemReporter.potentiallyUnclosedCloseable(this, location);
221
			else
222
				problemReporter.unclosedCloseable(this, location);
223
		} else if (nullStatus == FlowInfo.POTENTIALLY_NULL) {
224
			problemReporter.potentiallyUnclosedCloseable(this, location);
225
		}		
226
	}
227
228
	public void reportExplicitClosing(ProblemReporter problemReporter) {
229
		if ((this.globalClosingState & REPORTED) == 0) {
230
			this.globalClosingState |= REPORTED;
231
			problemReporter.explicitlyClosedAutoCloseable(this);
232
		}
233
		
234
	}
235
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java (-2 / +4 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 138-144 Link Here
138
						actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
140
						actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
139
					}
141
					}
140
				}
142
				}
141
			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
143
			if (this.action.complainIfUnreachable(actionInfo, flowContext, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
142
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalInits();
144
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalInits();
143
			}
145
			}
144
146
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java (-1 / +2 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 99-105 Link Here
99
		if (!(this.action == null || (this.action.isEmptyBlock()
100
		if (!(this.action == null || (this.action.isEmptyBlock()
100
				&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
101
				&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
101
102
102
			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
103
			if (this.action.complainIfUnreachable(actionInfo, flowContext, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
103
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
104
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
104
			}
105
			}
105
106
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java (-3 / +7 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 89-95 Link Here
89
		this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo);
91
		this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo);
90
		if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) {
92
		if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) {
91
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
93
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
92
				this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, initialComplaintLevel);
94
				this.thenStatement.complainIfUnreachable(thenFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
93
			} else {
95
			} else {
94
				// its a known coding pattern which should be tolerated by dead code analysis
96
				// its a known coding pattern which should be tolerated by dead code analysis
95
				// according to isKnowDeadCodePattern()
97
				// according to isKnowDeadCodePattern()
Lines 115-121 Link Here
115
		this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo);
117
		this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo);
116
		if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) {
118
		if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) {
117
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
119
			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
118
				this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, initialComplaintLevel);
120
				this.elseStatement.complainIfUnreachable(elseFlowInfo, flowContext, currentScope, initialComplaintLevel, false);
119
			} else {
121
			} else {
120
				// its a known coding pattern which should be tolerated by dead code analysis
122
				// its a known coding pattern which should be tolerated by dead code analysis
121
				// according to isKnowDeadCodePattern()
123
				// according to isKnowDeadCodePattern()
Lines 124-129 Link Here
124
		}
126
		}
125
		elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
127
		elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
126
	}
128
	}
129
	// process AutoCloseable resources closed in only one branch:
130
	currentScope.correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
127
	// merge THEN & ELSE initializations
131
	// merge THEN & ELSE initializations
128
	FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranchesIfElse(
132
	FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranchesIfElse(
129
		thenFlowInfo,
133
		thenFlowInfo,
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (+2 lines)
Lines 11-16 Link Here
11
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
11
 *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     						bug 292478 - Report potentially null across variable assignment
12
 *     						bug 292478 - Report potentially null across variable assignment
13
 *     						bug 335093 - [compiler][null] minimal hook for future null annotation support
13
 *     						bug 335093 - [compiler][null] minimal hook for future null annotation support
14
 *     						bug 349326 - [1.7] new warning for missing try-with-resources
14
 *******************************************************************************/
15
 *******************************************************************************/
15
package org.eclipse.jdt.internal.compiler.ast;
16
package org.eclipse.jdt.internal.compiler.ast;
16
17
Lines 76-81 Link Here
76
		this.initialization
77
		this.initialization
77
			.analyseCode(currentScope, flowContext, flowInfo)
78
			.analyseCode(currentScope, flowContext, flowInfo)
78
			.unconditionalInits();
79
			.unconditionalInits();
80
	FakedTrackingVariable.handleResourceAssignment(flowInfo, this, this.initialization, this.binding, null);
79
	int nullStatus = this.initialization.nullStatus(flowInfo);
81
	int nullStatus = this.initialization.nullStatus(flowInfo);
80
	if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
82
	if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
81
		this.bits |= FirstAssignmentToLocal;
83
		this.bits |= FirstAssignmentToLocal;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-1 / +18 lines)
Lines 8-14 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
10
 *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
11
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
11
 *     Stephan Herrmann - Contributions for
12
 *     	 						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
13
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
12
 *******************************************************************************/
14
 *******************************************************************************/
13
package org.eclipse.jdt.internal.compiler.ast;
15
package org.eclipse.jdt.internal.compiler.ast;
14
16
Lines 38-43 Link Here
38
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
40
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
39
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
41
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
40
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
42
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
43
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
41
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
44
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
42
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
45
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
43
46
Lines 60-65 Link Here
60
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
63
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
61
	boolean nonStatic = !this.binding.isStatic();
64
	boolean nonStatic = !this.binding.isStatic();
62
	flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
65
	flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
66
	// recording the closing of AutoCloseable resources:
67
	if (CharOperation.equals(TypeConstants.CLOSE, this.selector)) 
68
	{
69
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.receiver);
70
		if (trackingVariable != null) { // null happens if receiver is not a local variable or not an AutoCloseable
71
			if (trackingVariable.methodScope == currentScope.methodScope()) {
72
				trackingVariable.markClose(flowInfo, flowContext);
73
			} else {
74
				trackingVariable.markClosedInNestedMethod();
75
			}
76
		}
77
	}
63
	if (nonStatic) {
78
	if (nonStatic) {
64
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
79
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
65
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
80
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
Lines 80-85 Link Here
80
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
95
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
81
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
96
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
82
			}
97
			}
98
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
99
			flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo);
83
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
100
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
84
		}
101
		}
85
	}
102
	}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java (-1 / +3 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
package org.eclipse.jdt.internal.compiler.ast;
12
13
Lines 100-106 Link Here
100
				int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
101
				int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
101
				for (int i = 0, count = this.statements.length; i < count; i++) {
102
				for (int i = 0, count = this.statements.length; i < count; i++) {
102
					Statement stat = this.statements[i];
103
					Statement stat = this.statements[i];
103
					if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
104
					if ((complaintLevel = stat.complainIfUnreachable(flowInfo, methodContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
104
						flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo);
105
						flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo);
105
					}
106
					}
106
				}
107
				}
Lines 134-139 Link Here
134
				}
135
				}
135
					
136
					
136
			}
137
			}
138
			this.scope.checkUnclosedCloseables(flowInfo, methodContext, null/*don't report against a specific location*/);
137
		} catch (AbortMethod e) {
139
		} catch (AbortMethod e) {
138
			this.ignoreFurtherInvestigation = true;
140
			this.ignoreFurtherInvestigation = true;
139
		}
141
		}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java (-1 / +5 lines)
Lines 7-13 Link Here
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 72-77 Link Here
72
		// process arguments
74
		// process arguments
73
		if (this.arguments != null) {
75
		if (this.arguments != null) {
74
			for (int i = 0, count = this.arguments.length; i < count; i++) {
76
			for (int i = 0, count = this.arguments.length; i < count; i++) {
77
				// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
78
				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo);
75
				flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
79
				flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
76
				if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
80
				if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
77
					this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
81
					this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (-1 / +12 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 39-44 Link Here
39
		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
41
		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
40
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
42
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
41
			this.expression.checkNPE(currentScope, flowContext, flowInfo);
43
			this.expression.checkNPE(currentScope, flowContext, flowInfo);
44
		}
45
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
46
		if (trackingVariable != null) {
47
			if (currentScope.methodScope() != trackingVariable.methodScope)
48
				trackingVariable.markClosedInNestedMethod();
49
			// don't report issues concerning this local, since by returning
50
			// the method passes the responsibility to the caller:
51
			currentScope.removeTrackingVar(trackingVariable);
42
		}
52
		}
43
	}
53
	}
44
	this.initStateIndex =
54
	this.initStateIndex =
Lines 104-109 Link Here
104
			this.expression.bits |= ASTNode.IsReturnedValue;
114
			this.expression.bits |= ASTNode.IsReturnedValue;
105
		}
115
		}
106
	}
116
	}
117
	currentScope.checkUnclosedCloseables(flowInfo, null/*ignore exception exits from flowContext*/, this);
107
	return FlowInfo.DEAD_END;
118
	return FlowInfo.DEAD_END;
108
}
119
}
109
120
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java (-2 / +8 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 335093 - [compiler][null] minimal hook for future null annotation support
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 335093 - [compiler][null] minimal hook for future null annotation support
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 70-87 Link Here
70
72
71
// Report an error if necessary (if even more unreachable than previously reported
73
// Report an error if necessary (if even more unreachable than previously reported
72
// complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error)
74
// complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error)
73
public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel) {
75
public int complainIfUnreachable(FlowInfo flowInfo, FlowContext flowContext, BlockScope scope, int previousComplaintLevel, boolean endOfBlock) {
74
	if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
76
	if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
75
		if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
77
		if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
76
			this.bits &= ~ASTNode.IsReachable;
78
			this.bits &= ~ASTNode.IsReachable;
77
		if (flowInfo == FlowInfo.DEAD_END) {
79
		if (flowInfo == FlowInfo.DEAD_END) {
78
			if (previousComplaintLevel < COMPLAINED_UNREACHABLE) {
80
			if (previousComplaintLevel < COMPLAINED_UNREACHABLE) {
79
				scope.problemReporter().unreachableCode(this);
81
				scope.problemReporter().unreachableCode(this);
82
				if (endOfBlock)
83
					scope.checkUnclosedCloseables(flowInfo, flowContext, null);
80
			}
84
			}
81
			return COMPLAINED_UNREACHABLE;
85
			return COMPLAINED_UNREACHABLE;
82
		} else {
86
		} else {
83
			if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) {
87
			if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) {
84
				scope.problemReporter().fakeReachable(this);
88
				scope.problemReporter().fakeReachable(this);
89
				if (endOfBlock)
90
					scope.checkUnclosedCloseables(flowInfo, flowContext, null);
85
			}
91
			}
86
			return COMPLAINED_FAKE_REACHABLE;
92
			return COMPLAINED_FAKE_REACHABLE;
87
		}
93
		}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java (-2 / +4 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 99-105 Link Here
99
					} else {
101
					} else {
100
						fallThroughState = FALLTHROUGH; // reset below if needed
102
						fallThroughState = FALLTHROUGH; // reset below if needed
101
					}
103
					}
102
					if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
104
					if ((complaintLevel = statement.complainIfUnreachable(caseInits, flowContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
103
						caseInits = statement.analyseCode(this.scope, switchContext, caseInits);
105
						caseInits = statement.analyseCode(this.scope, switchContext, caseInits);
104
						if (caseInits == FlowInfo.DEAD_END) {
106
						if (caseInits == FlowInfo.DEAD_END) {
105
							fallThroughState = ESCAPING;
107
							fallThroughState = ESCAPING;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java (-4 / +17 lines)
Lines 10-15 Link Here
10
 *     Stephan Herrmann - Contributions for
10
 *     Stephan Herrmann - Contributions for
11
 *     							bug 332637 - Dead Code detection removing code that isn't dead
11
 *     							bug 332637 - Dead Code detection removing code that isn't dead
12
 *     							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
12
 *     							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
13
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
13
 *******************************************************************************/
14
 *******************************************************************************/
14
package org.eclipse.jdt.internal.compiler.ast;
15
package org.eclipse.jdt.internal.compiler.ast;
15
16
Lines 126-133 Link Here
126
		for (int i = 0; i < resourcesLength; i++) {
127
		for (int i = 0; i < resourcesLength; i++) {
127
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
128
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
128
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
129
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
129
			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
130
			LocalVariableBinding resourceBinding = this.resources[i].binding;
130
			TypeBinding type = this.resources[i].binding.type;
131
			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
132
			if (resourceBinding.closeTracker != null) {
133
				// this was false alarm, we don't need to track the resource
134
				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
135
				resourceBinding.closeTracker = null;
136
			}
137
			TypeBinding type = resourceBinding.type;
131
			if (type != null && type.isValidBinding()) {
138
			if (type != null && type.isValidBinding()) {
132
				ReferenceBinding binding = (ReferenceBinding) type;
139
				ReferenceBinding binding = (ReferenceBinding) type;
133
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
140
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
Lines 252-259 Link Here
252
		for (int i = 0; i < resourcesLength; i++) {
259
		for (int i = 0; i < resourcesLength; i++) {
253
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
260
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
254
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
261
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
255
			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
262
			LocalVariableBinding resourceBinding = this.resources[i].binding;
256
			TypeBinding type = this.resources[i].binding.type;
263
			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
264
			if (resourceBinding.closeTracker != null) {
265
				// this was false alarm, we don't need to track the resource
266
				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
267
				resourceBinding.closeTracker = null;
268
			} 
269
			TypeBinding type = resourceBinding.type;
257
			if (type != null && type.isValidBinding()) {
270
			if (type != null && type.isValidBinding()) {
258
				ReferenceBinding binding = (ReferenceBinding) type;
271
				ReferenceBinding binding = (ReferenceBinding) type;
259
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
272
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java (-2 / +4 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.ast;
14
package org.eclipse.jdt.internal.compiler.ast;
13
15
Lines 113-119 Link Here
113
				currentScope.methodScope().recordInitializationStates(
115
				currentScope.methodScope().recordInitializationStates(
114
					condInfo.initsWhenTrue());
116
					condInfo.initsWhenTrue());
115
117
116
			if (this.action.complainIfUnreachable(actionInfo, currentScope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
118
			if (this.action.complainIfUnreachable(actionInfo, flowContext, currentScope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
117
				actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo);
119
				actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo);
118
			}
120
			}
119
121
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (-6 / +7 lines)
Lines 13-18 Link Here
13
 *     						bug 292478 - Report potentially null across variable assignment
13
 *     						bug 292478 - Report potentially null across variable assignment
14
 *     						bug 332637 - Dead Code detection removing code that isn't dead
14
 *     						bug 332637 - Dead Code detection removing code that isn't dead
15
 *     						bug 341499 - [compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo
15
 *     						bug 341499 - [compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo
16
 *     						bug 349326 - [1.7] new warning for missing try-with-resources
16
 *******************************************************************************/
17
 *******************************************************************************/
17
package org.eclipse.jdt.internal.compiler.flow;
18
package org.eclipse.jdt.internal.compiler.flow;
18
19
Lines 770-776 Link Here
770
	}
771
	}
771
	int vectorIndex;
772
	int vectorIndex;
772
	if ((vectorIndex = (position / BitCacheSize) - 1)
773
	if ((vectorIndex = (position / BitCacheSize) - 1)
773
			>= this.extra[0].length) {
774
			>= this.extra[2].length) {
774
		return false; // if not enough room in vector, then not initialized
775
		return false; // if not enough room in vector, then not initialized
775
	}
776
	}
776
	return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
777
	return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
Lines 797-803 Link Here
797
	}
798
	}
798
	int vectorIndex;
799
	int vectorIndex;
799
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
800
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
800
			this.extra[0].length) {
801
			this.extra[2].length) {
801
		return false; // if not enough room in vector, then not initialized
802
		return false; // if not enough room in vector, then not initialized
802
	}
803
	}
803
	return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
804
	return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
Lines 822-828 Link Here
822
	}
823
	}
823
	int vectorIndex;
824
	int vectorIndex;
824
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
825
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
825
			this.extra[0].length) {
826
			this.extra[2].length) {
826
		return false; // if not enough room in vector, then not initialized
827
		return false; // if not enough room in vector, then not initialized
827
	}
828
	}
828
	return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex]
829
	return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex]
Lines 882-888 Link Here
882
	}
883
	}
883
	int vectorIndex;
884
	int vectorIndex;
884
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
885
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
885
			this.extra[0].length) {
886
			this.extra[2].length) {
886
		return false; // if not enough room in vector, then not initialized
887
		return false; // if not enough room in vector, then not initialized
887
	}
888
	}
888
	return ((this.extra[4][vectorIndex]
889
	return ((this.extra[4][vectorIndex]
Lines 908-914 Link Here
908
	}
909
	}
909
	int vectorIndex;
910
	int vectorIndex;
910
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
911
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
911
			this.extra[0].length) {
912
			this.extra[2].length) {
912
		return false; // if not enough room in vector, then not initialized
913
		return false; // if not enough room in vector, then not initialized
913
	}
914
	}
914
	return ((this.extra[3][vectorIndex]
915
	return ((this.extra[3][vectorIndex]
Lines 934-940 Link Here
934
	}
935
	}
935
	int vectorIndex;
936
	int vectorIndex;
936
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
937
	if ((vectorIndex = (position / BitCacheSize) - 1) >=
937
			this.extra[0].length) {
938
			this.extra[2].length) {
938
		return false; // if not enough room in vector, then not initialized
939
		return false; // if not enough room in vector, then not initialized
939
	}
940
	}
940
	return (this.extra[5][vectorIndex]
941
	return (this.extra[5][vectorIndex]
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java (-4 / +38 lines)
Lines 8-15 Link Here
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Benjamin Muskalla - Contribution for bug 239066
10
 *     Benjamin Muskalla - Contribution for bug 239066
11
 *     Stephan Herrmann  - Contribution for bug 236385
11
 *     Stephan Herrmann  - Contributions for
12
 *     Stephan Herrmann  - Contribution for bug 295551
12
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
13
 *     							bug 295551 - Add option to automatically promote all warnings to errors
14
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
13
 *******************************************************************************/
15
 *******************************************************************************/
14
package org.eclipse.jdt.internal.compiler.impl;
16
package org.eclipse.jdt.internal.compiler.impl;
15
17
Lines 137-142 Link Here
137
	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
139
	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
138
	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
140
	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
139
	public static final String OPTION_ReportRedundantSpecificationOfTypeArguments =  "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$
141
	public static final String OPTION_ReportRedundantSpecificationOfTypeArguments =  "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$
142
	public static final String OPTION_ReportUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.unclosedCloseable"; //$NON-NLS-1$
143
	public static final String OPTION_ReportPotentiallyUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
144
	public static final String OPTION_ReportExplicitlyClosedAutoCloseable = "org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
140
	/**
145
	/**
141
	 * Possible values for configurable options
146
	 * Possible values for configurable options
142
	 */
147
	 */
Lines 240-245 Link Here
240
	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
245
	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
241
	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
246
	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
242
	public static final int RedundantSpecificationOfTypeArguments = IrritantSet.GROUP2 | ASTNode.Bit7;
247
	public static final int RedundantSpecificationOfTypeArguments = IrritantSet.GROUP2 | ASTNode.Bit7;
248
	// bits 8-10 reserved for https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342
249
	public static final int UnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit11;
250
	public static final int PotentiallyUnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit12;
251
	public static final int ExplicitlyClosedAutoCloseable = IrritantSet.GROUP2 | ASTNode.Bit13;
243
252
244
	// Severity level for handlers
253
	// Severity level for handlers
245
	/** 
254
	/** 
Lines 376-383 Link Here
376
		"javadoc", //$NON-NLS-1$
385
		"javadoc", //$NON-NLS-1$
377
		"nls", //$NON-NLS-1$
386
		"nls", //$NON-NLS-1$
378
		"null", //$NON-NLS-1$
387
		"null", //$NON-NLS-1$
379
		"restriction", //$NON-NLS-1$
380
		"rawtypes", //$NON-NLS-1$
388
		"rawtypes", //$NON-NLS-1$
389
		"resource", //$NON-NLS-1$
390
		"restriction", //$NON-NLS-1$		
381
		"serial", //$NON-NLS-1$
391
		"serial", //$NON-NLS-1$
382
		"static-access", //$NON-NLS-1$
392
		"static-access", //$NON-NLS-1$
383
		"static-method", //$NON-NLS-1$
393
		"static-method", //$NON-NLS-1$
Lines 551-556 Link Here
551
				return OPTION_ReportMethodCanBePotentiallyStatic;
561
				return OPTION_ReportMethodCanBePotentiallyStatic;
552
			case RedundantSpecificationOfTypeArguments :
562
			case RedundantSpecificationOfTypeArguments :
553
				return OPTION_ReportRedundantSpecificationOfTypeArguments;
563
				return OPTION_ReportRedundantSpecificationOfTypeArguments;
564
			case UnclosedCloseable :
565
				return OPTION_ReportUnclosedCloseable;
566
			case PotentiallyUnclosedCloseable :
567
				return OPTION_ReportPotentiallyUnclosedCloseable;
568
			case ExplicitlyClosedAutoCloseable :
569
				return OPTION_ReportExplicitlyClosedAutoCloseable;
554
		}
570
		}
555
		return null;
571
		return null;
556
	}
572
	}
Lines 714-719 Link Here
714
			OPTION_ReportUnusedTypeArgumentsForMethodInvocation,
730
			OPTION_ReportUnusedTypeArgumentsForMethodInvocation,
715
			OPTION_ReportUnusedWarningToken,
731
			OPTION_ReportUnusedWarningToken,
716
			OPTION_ReportVarargsArgumentNeedCast,
732
			OPTION_ReportVarargsArgumentNeedCast,
733
			OPTION_ReportUnclosedCloseable,
734
			OPTION_ReportPotentiallyUnclosedCloseable,
735
			OPTION_ReportExplicitlyClosedAutoCloseable,
717
		};
736
		};
718
		return result;
737
		return result;
719
	}
738
	}
Lines 784-793 Link Here
784
			case MethodCanBeStatic :
803
			case MethodCanBeStatic :
785
			case MethodCanBePotentiallyStatic :
804
			case MethodCanBePotentiallyStatic :
786
				return "static-method"; //$NON-NLS-1$
805
				return "static-method"; //$NON-NLS-1$
806
			case PotentiallyUnclosedCloseable:
807
			case UnclosedCloseable:
808
			case ExplicitlyClosedAutoCloseable:
809
				return "resource"; //$NON-NLS-1$
787
			case InvalidJavadoc :
810
			case InvalidJavadoc :
788
			case MissingJavadocComments :
811
			case MissingJavadocComments :
789
			case MissingJavadocTags:
812
			case MissingJavadocTags:
790
				return "javadoc"; //$NON-NLS-1$				
813
				return "javadoc"; //$NON-NLS-1$
791
		}
814
		}
792
		return null;
815
		return null;
793
	}
816
	}
Lines 841-846 Link Here
841
			case 'r' :
864
			case 'r' :
842
				if ("rawtypes".equals(warningToken)) //$NON-NLS-1$
865
				if ("rawtypes".equals(warningToken)) //$NON-NLS-1$
843
					return IrritantSet.RAW;
866
					return IrritantSet.RAW;
867
				if ("resource".equals(warningToken)) //$NON-NLS-1$
868
					return IrritantSet.RESOURCE;
844
				if ("restriction".equals(warningToken)) //$NON-NLS-1$
869
				if ("restriction".equals(warningToken)) //$NON-NLS-1$
845
					return IrritantSet.RESTRICTION;
870
					return IrritantSet.RESTRICTION;
846
				break;
871
				break;
Lines 980-985 Link Here
980
		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
1005
		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
981
		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
1006
		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
982
		optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments));
1007
		optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments));
1008
		optionsMap.put(OPTION_ReportUnclosedCloseable, getSeverityString(UnclosedCloseable));
1009
		optionsMap.put(OPTION_ReportPotentiallyUnclosedCloseable, getSeverityString(PotentiallyUnclosedCloseable));
1010
		optionsMap.put(OPTION_ReportExplicitlyClosedAutoCloseable, getSeverityString(ExplicitlyClosedAutoCloseable));
983
		return optionsMap;
1011
		return optionsMap;
984
	}
1012
	}
985
1013
Lines 1410-1415 Link Here
1410
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
1438
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
1411
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
1439
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
1412
		if ((optionValue = optionsMap.get(OPTION_ReportRedundantSpecificationOfTypeArguments)) != null) updateSeverity(RedundantSpecificationOfTypeArguments, optionValue);
1440
		if ((optionValue = optionsMap.get(OPTION_ReportRedundantSpecificationOfTypeArguments)) != null) updateSeverity(RedundantSpecificationOfTypeArguments, optionValue);
1441
		if ((optionValue = optionsMap.get(OPTION_ReportUnclosedCloseable)) != null) updateSeverity(UnclosedCloseable, optionValue);
1442
		if ((optionValue = optionsMap.get(OPTION_ReportPotentiallyUnclosedCloseable)) != null) updateSeverity(PotentiallyUnclosedCloseable, optionValue);
1443
		if ((optionValue = optionsMap.get(OPTION_ReportExplicitlyClosedAutoCloseable)) != null) updateSeverity(ExplicitlyClosedAutoCloseable, optionValue);
1413
1444
1414
		// Javadoc options
1445
		// Javadoc options
1415
		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
1446
		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
Lines 1625-1630 Link Here
1625
		buf.append("\n\t- method can be static: ").append(getSeverityString(MethodCanBeStatic)); //$NON-NLS-1$
1656
		buf.append("\n\t- method can be static: ").append(getSeverityString(MethodCanBeStatic)); //$NON-NLS-1$
1626
		buf.append("\n\t- method can be potentially static: ").append(getSeverityString(MethodCanBePotentiallyStatic)); //$NON-NLS-1$
1657
		buf.append("\n\t- method can be potentially static: ").append(getSeverityString(MethodCanBePotentiallyStatic)); //$NON-NLS-1$
1627
		buf.append("\n\t- redundant specification of type arguments: ").append(getSeverityString(RedundantSpecificationOfTypeArguments)); //$NON-NLS-1$
1658
		buf.append("\n\t- redundant specification of type arguments: ").append(getSeverityString(RedundantSpecificationOfTypeArguments)); //$NON-NLS-1$
1659
		buf.append("\n\t- resource is not closed: ").append(getSeverityString(UnclosedCloseable)); //$NON-NLS-1$
1660
		buf.append("\n\t- resource may not be closed: ").append(getSeverityString(PotentiallyUnclosedCloseable)); //$NON-NLS-1$
1661
		buf.append("\n\t- resource should be handled by try-with-resources: ").append(getSeverityString(ExplicitlyClosedAutoCloseable)); //$NON-NLS-1$
1628
		return buf.toString();
1662
		return buf.toString();
1629
	}
1663
	}
1630
	
1664
	
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java (-1 / +7 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
12
12
package org.eclipse.jdt.internal.compiler.impl;
13
package org.eclipse.jdt.internal.compiler.impl;
Lines 57-62 Link Here
57
	public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
58
	public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
58
	public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
59
	public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
59
	public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
60
	public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
61
	public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable);
60
62
61
	public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
63
	public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
62
	public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default	
64
	public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default	
Lines 99-105 Link Here
99
			// group-2 warnings enabled by default
101
			// group-2 warnings enabled by default
100
			.set(
102
			.set(
101
				CompilerOptions.DeadCode
103
				CompilerOptions.DeadCode
102
				|CompilerOptions.Tasks);
104
				|CompilerOptions.Tasks
105
				|CompilerOptions.UnclosedCloseable);
103
			
106
			
104
		ALL.setAll();
107
		ALL.setAll();
105
		HIDING
108
		HIDING
Lines 124-129 Link Here
124
			.set(CompilerOptions.RedundantSpecificationOfTypeArguments);
127
			.set(CompilerOptions.RedundantSpecificationOfTypeArguments);
125
		STATIC_METHOD
128
		STATIC_METHOD
126
		    .set(CompilerOptions.MethodCanBePotentiallyStatic);
129
		    .set(CompilerOptions.MethodCanBePotentiallyStatic);
130
		RESOURCE
131
			.set(CompilerOptions.PotentiallyUnclosedCloseable)
132
			.set(CompilerOptions.ExplicitlyClosedAutoCloseable);
127
		String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
133
		String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
128
		if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$
134
		if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$
129
			UNCHECKED.set(CompilerOptions.RawTypeReference);
135
			UNCHECKED.set(CompilerOptions.RawTypeReference);
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java (-2 / +21 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 972-977 Link Here
972
	variable.resolve();
973
	variable.resolve();
973
	return variable;
974
	return variable;
974
}
975
}
976
public boolean hasTypeBit(int bit) {
977
	// ensure hierarchy is resolved, which will propagate bits down to us
978
	superclass();
979
	superInterfaces();
980
	return (this.typeBits & bit) != 0;
981
}
975
private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) {
982
private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) {
976
	// ParameterSignature = Identifier ':' TypeSignature
983
	// ParameterSignature = Identifier ':' TypeSignature
977
	//   or Identifier ':' TypeSignature(optional) InterfaceBound(s)
984
	//   or Identifier ':' TypeSignature(optional) InterfaceBound(s)
Lines 1140-1147 Link Here
1140
	// finish resolving the type
1147
	// finish resolving the type
1141
	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */);
1148
	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */);
1142
	this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
1149
	this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
1143
	if (this.superclass.problemId() == ProblemReasons.NotFound)
1150
	if (this.superclass.problemId() == ProblemReasons.NotFound) {
1144
		this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1151
		this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1152
	} else {
1153
		// make super-type resolving recursive for propagating typeBits downwards
1154
		this.superclass.superclass();
1155
		this.superclass.superInterfaces();
1156
	}
1157
	this.typeBits |= this.superclass.typeBits;
1145
	return this.superclass;
1158
	return this.superclass;
1146
}
1159
}
1147
// NOTE: superInterfaces of binary types are resolved when needed
1160
// NOTE: superInterfaces of binary types are resolved when needed
Lines 1151-1158 Link Here
1151
1164
1152
	for (int i = this.superInterfaces.length; --i >= 0;) {
1165
	for (int i = this.superInterfaces.length; --i >= 0;) {
1153
		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */);
1166
		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */);
1154
		if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound)
1167
		if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) {
1155
			this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1168
			this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1169
		} else {
1170
			// make super-type resolving recursive for propagating typeBits downwards
1171
			this.superInterfaces[i].superclass();
1172
			this.superInterfaces[i].superInterfaces();
1173
		}
1174
		this.typeBits |= this.superInterfaces[i].typeBits;
1156
	}
1175
	}
1157
	this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
1176
	this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
1158
	return this.superInterfaces;
1177
	return this.superInterfaces;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (+147 lines)
Lines 7-19 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
13
14
import java.util.ArrayList;
15
import java.util.List;
12
16
13
import org.eclipse.jdt.core.compiler.CharOperation;
17
import org.eclipse.jdt.core.compiler.CharOperation;
14
import org.eclipse.jdt.internal.compiler.ast.*;
18
import org.eclipse.jdt.internal.compiler.ast.*;
15
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
21
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
22
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
17
import org.eclipse.jdt.internal.compiler.impl.Constant;
23
import org.eclipse.jdt.internal.compiler.impl.Constant;
18
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
24
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
19
25
Lines 957-960 Link Here
957
		}
963
		}
958
	}
964
	}
959
}
965
}
966
967
private List trackingVariables; // can be null if no resources are tracked
968
/**
969
 * Register a tracking variable and compute its id.
970
 */
971
public int registerTrackingVariable(FakedTrackingVariable fakedTrackingVariable) {
972
	if (this.trackingVariables == null)
973
		this.trackingVariables = new ArrayList(3);
974
	this.trackingVariables.add(fakedTrackingVariable);
975
	MethodScope outerMethodScope = outerMostMethodScope();
976
	return outerMethodScope.analysisIndex + (outerMethodScope.trackVarCount++);
977
	
978
}
979
/** When no longer interested in this tracking variable remove it. */
980
public void removeTrackingVar(FakedTrackingVariable trackingVariable) {
981
	if (this.trackingVariables != null)
982
		if (this.trackingVariables.remove(trackingVariable))
983
			return;
984
	if (this.parent instanceof BlockScope)
985
		((BlockScope)this.parent).removeTrackingVar(trackingVariable);
986
}
987
/**
988
 * At the end of a block check the closing-status of all tracked closeables that are declared in this block.
989
 * Also invoked when entering unreachable code.
990
 */
991
public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location) {
992
	if (this.trackingVariables == null) {
993
		// at a method return we also consider enclosing scopes
994
		if (location != null && this.parent instanceof BlockScope)
995
			((BlockScope) this.parent).checkUnclosedCloseables(flowInfo, flowContext, location);
996
		return;
997
	}
998
	if (location != null && flowInfo.reachMode() != 0) return;
999
	for (int i=0; i<this.trackingVariables.size(); i++) {
1000
		FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
1001
		if (location != null && trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding))
1002
			continue; // reporting against a specific location, resource is null at this flow, don't complain
1003
		int status = getNullStatusAggressively(trackingVar.binding, flowInfo);
1004
		if (status == FlowInfo.NULL) {
1005
			// definitely unclosed: highest priority
1006
			reportResourceLeak(trackingVar, location, status);
1007
			if (location == null) {
1008
				// definitely done with this trackingVar, remove it
1009
				this.trackingVariables.remove(trackingVar);
1010
				i--; // ... but don't disturb the enclosing loop.
1011
			}
1012
			continue;
1013
		}
1014
		if (location == null) // at end of block and not definitely unclosed
1015
		{
1016
			// problems at specific locations: medium priority
1017
			if (trackingVar.reportRecordedErrors(this)) // ... report previously recorded errors
1018
				continue;
1019
		} 
1020
		if (status == FlowInfo.POTENTIALLY_NULL) {
1021
			// potentially unclosed: lower priority
1022
			reportResourceLeak(trackingVar, location, status);
1023
		} else if (status == FlowInfo.NON_NULL) {
1024
			// properly closed but not managed by t-w-r: lowest priority 
1025
			if (environment().globalOptions.complianceLevel >= ClassFileConstants.JDK1_7)
1026
				trackingVar.reportExplicitClosing(problemReporter());
1027
		}
1028
	}
1029
}
1030
private void reportResourceLeak(FakedTrackingVariable trackingVar, ASTNode location, int nullStatus) {
1031
	if (location != null)
1032
		trackingVar.recordErrorLocation(location, nullStatus);
1033
	else
1034
		trackingVar.reportError(problemReporter(), null, nullStatus);
1035
}
1036
1037
/** 
1038
 * If one branch of an if-else closes any AutoCloseable resource, and if the same
1039
 * resource is known to be null on the other branch mark it as closed, too,
1040
 * so that merging both branches indicates that the resource is always closed.
1041
 * Example:
1042
 *	FileReader fr1 = null;
1043
 *	try {\n" +
1044
 *      fr1 = new FileReader(someFile);" + 
1045
 *		fr1.read(buf);\n" + 
1046
 *	} finally {\n" + 
1047
 *		if (fr1 != null)\n" +
1048
 *           try {\n" +
1049
 *               fr1.close();\n" +
1050
 *           } catch (IOException e) {
1051
 *              // do nothing 
1052
 *           }
1053
 *      // after this if statement fr1 is definitely not leaked 
1054
 *	}
1055
 */
1056
public void correlateTrackingVarsIfElse(FlowInfo thenFlowInfo, FlowInfo elseFlowInfo) {
1057
	if (this.trackingVariables != null) {
1058
		for (int i=0; i<this.trackingVariables.size(); i++) {
1059
			FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
1060
			if (   thenFlowInfo.isDefinitelyNonNull(trackingVar.binding)			// closed in then branch
1061
				&& elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding))		// null in else branch
1062
			{
1063
				elseFlowInfo.markAsDefinitelyNonNull(trackingVar.binding);			// -> always closed
1064
			}
1065
			else if (   elseFlowInfo.isDefinitelyNonNull(trackingVar.binding)		// closed in else branch
1066
					 && thenFlowInfo.isDefinitelyNull(trackingVar.originalBinding))	// null in then branch
1067
			{
1068
				thenFlowInfo.markAsDefinitelyNonNull(trackingVar.binding);			// -> always closed
1069
			}
1070
		}
1071
	}
1072
	if (this.parent instanceof BlockScope)
1073
		((BlockScope) this.parent).correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
1074
}
1075
1076
/**
1077
 * Get the null status looking even into unreachable flows
1078
 * @param local
1079
 * @param flowInfo
1080
 * @return one of the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}.
1081
 */
1082
private int getNullStatusAggressively(LocalVariableBinding local, FlowInfo flowInfo) {
1083
	int reachMode = flowInfo.reachMode();
1084
	int status = 0;
1085
	try {
1086
		// unreachable flowInfo is too shy in reporting null-issues, temporarily forget reachability:
1087
		if (reachMode != FlowInfo.REACHABLE)
1088
			flowInfo.tagBits &= ~FlowInfo.UNREACHABLE;
1089
		status = flowInfo.nullStatus(local);
1090
	} finally {
1091
		// reset
1092
		flowInfo.tagBits |= reachMode;
1093
	}
1094
	// at this point some combinations are not useful so flatten to a single bit:
1095
	if ((status & FlowInfo.NULL) != 0) {
1096
		if ((status & (FlowInfo.NON_NULL | FlowInfo.POTENTIALLY_NON_NULL)) != 0)
1097
			return FlowInfo.POTENTIALLY_NULL; 	// null + doubt = pot null
1098
		return FlowInfo.NULL;
1099
	} else if ((status & FlowInfo.NON_NULL) != 0) {
1100
		if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
1101
			return FlowInfo.POTENTIALLY_NULL;	// non-null + doubt = pot null
1102
		return FlowInfo.NON_NULL;
1103
	} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
1104
		return FlowInfo.POTENTIALLY_NULL;
1105
	return status;
1106
}
960
}
1107
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java (+3 lines)
Lines 11-16 Link Here
11
 *     						Bug 328281 - visibility leaks not detected when analyzing unused field in private class
11
 *     						Bug 328281 - visibility leaks not detected when analyzing unused field in private class
12
 *     						Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
12
 *     						Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
13
 *     						Bug 354536 - compiling package-info.java still depends on the order of compilation units
13
 *     						Bug 354536 - compiling package-info.java still depends on the order of compilation units
14
 *     						Bug 349326 - [1.7] new warning for missing try-with-resources
14
 *******************************************************************************/
15
 *******************************************************************************/
15
package org.eclipse.jdt.internal.compiler.lookup;
16
package org.eclipse.jdt.internal.compiler.lookup;
16
17
Lines 908-913 Link Here
908
			} else {
909
			} else {
909
				// only want to reach here when no errors are reported
910
				// only want to reach here when no errors are reported
910
				sourceType.superclass = superclass;
911
				sourceType.superclass = superclass;
912
				sourceType.typeBits |= superclass.typeBits;
911
				return true;
913
				return true;
912
			}
914
			}
913
		}
915
		}
Lines 1023-1028 Link Here
1023
				noProblems &= superInterfaceRef.resolvedType.isValidBinding();
1025
				noProblems &= superInterfaceRef.resolvedType.isValidBinding();
1024
			}
1026
			}
1025
			// only want to reach here when no errors are reported
1027
			// only want to reach here when no errors are reported
1028
			sourceType.typeBits |= superInterface.typeBits;
1026
			interfaceBindings[count++] = superInterface;
1029
			interfaceBindings[count++] = superInterface;
1027
		}
1030
		}
1028
		// hold onto all correctly resolved superinterfaces
1031
		// hold onto all correctly resolved superinterfaces
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java (-1 / +6 lines)
Lines 7-13 Link Here
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
11
 *     							bug 185682 - Increment/decrement operators mark local variables as read
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
14
package org.eclipse.jdt.internal.compiler.lookup;
13
15
Lines 15-20 Link Here
15
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
17
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
16
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
18
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
17
import org.eclipse.jdt.internal.compiler.ast.Annotation;
19
import org.eclipse.jdt.internal.compiler.ast.Annotation;
20
import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
18
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
21
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
19
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
22
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
20
import org.eclipse.jdt.internal.compiler.impl.Constant;
23
import org.eclipse.jdt.internal.compiler.impl.Constant;
Lines 35-40 Link Here
35
	public int[] initializationPCs;
38
	public int[] initializationPCs;
36
	public int initializationCount = 0;
39
	public int initializationCount = 0;
37
40
41
	public FakedTrackingVariable closeTracker; // track closing of instances of type AutoCloseable, maybe null
42
38
	// for synthetic local variables
43
	// for synthetic local variables
39
	// if declaration slot is not positionned, the variable will not be listed in attribute
44
	// if declaration slot is not positionned, the variable will not be listed in attribute
40
	// note that the name of a variable should be chosen so as not to conflict with user ones (usually starting with a space char is all needed)
45
	// note that the name of a variable should be chosen so as not to conflict with user ones (usually starting with a space char is all needed)
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java (+4 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 49-54 Link Here
49
	// inner-emulation
50
	// inner-emulation
50
	public SyntheticArgumentBinding[] extraSyntheticArguments;
51
	public SyntheticArgumentBinding[] extraSyntheticArguments;
51
52
53
	// count number of tracking variables, see FakedTrackingVariable
54
	int trackVarCount = 0;
55
52
public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) {
56
public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) {
53
	super(METHOD_SCOPE, parent);
57
	super(METHOD_SCOPE, parent);
54
	this.locals = new LocalVariableBinding[5];
58
	this.locals = new LocalVariableBinding[5];
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java (+8 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 629-634 Link Here
629
	    return this.type.hasMemberTypes();
630
	    return this.type.hasMemberTypes();
630
	}
631
	}
631
632
633
	public boolean hasTypeBit(int bit) {
634
		TypeBinding erasure = erasure();
635
		if (erasure instanceof ReferenceBinding)
636
			return ((ReferenceBinding) erasure).hasTypeBit(bit);
637
		return false;
638
	}
639
632
	/**
640
	/**
633
	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding)
641
	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding)
634
	 */
642
	 */
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java (+7 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 40-45 Link Here
40
	return this.closestMatch;
41
	return this.closestMatch;
41
}
42
}
42
43
44
public boolean hasTypeBit(int bit) {
45
	if (this.closestMatch != null)
46
		return this.closestMatch.hasTypeBit(bit);
47
	return false;
48
}
49
43
/* API
50
/* API
44
* Answer the problem id associated with the receiver.
51
* Answer the problem id associated with the receiver.
45
* NoError if the receiver is a valid binding.
52
* NoError if the receiver is a valid binding.
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java (-2 / +15 lines)
Lines 7-12 Link Here
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 41-47 Link Here
41
42
42
	private SimpleLookupTable compatibleCache;
43
	private SimpleLookupTable compatibleCache;
43
44
44
	public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */};
45
	int typeBits; // additional bits characterizing this type
46
47
	public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */
48
		public boolean hasTypeBit(int bit) { return false; }
49
	};
45
50
46
	private static final Comparator FIELD_COMPARATOR = new Comparator() {
51
	private static final Comparator FIELD_COMPARATOR = new Comparator() {
47
		public int compare(Object o1, Object o2) {
52
		public int compare(Object o1, Object o2) {
Lines 392-397 Link Here
392
					case 'i' :
397
					case 'i' :
393
						if (CharOperation.equals(packageName, TypeConstants.IO)) {
398
						if (CharOperation.equals(packageName, TypeConstants.IO)) {
394
							switch (typeName[0]) {
399
							switch (typeName[0]) {
400
								case 'C' :
401
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2]))
402
										this.typeBits |= TypeIds.BitCloseable; // don't assign id, only typeBit (for analysis of resource leaks) 
403
									return;
395
								case 'E' :
404
								case 'E' :
396
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2]))
405
									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2]))
397
										this.id = TypeIds.T_JavaIoExternalizable;
406
										this.id = TypeIds.T_JavaIoExternalizable;
Lines 438-445 Link Here
438
				case 'A' :
447
				case 'A' :
439
					switch(typeName.length) {
448
					switch(typeName.length) {
440
						case 13 :
449
						case 13 :
441
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2]))
450
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
442
								this.id = TypeIds.T_JavaLangAutoCloseable;
451
								this.id = TypeIds.T_JavaLangAutoCloseable;
452
								this.typeBits |= TypeIds.BitAutoCloseable; 
453
							}
443
							return;
454
							return;
444
						case 14:
455
						case 14:
445
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
456
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
Lines 937-942 Link Here
937
public final boolean hasRestrictedAccess() {
948
public final boolean hasRestrictedAccess() {
938
	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
949
	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
939
}
950
}
951
/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */
952
abstract public boolean hasTypeBit(int bit);
940
953
941
/** Answer true if the receiver implements anInterface or is identical to anInterface.
954
/** Answer true if the receiver implements anInterface or is identical to anInterface.
942
* If searchHierarchy is true, then also search the receiver's superclasses.
955
* If searchHierarchy is true, then also search the receiver's superclasses.
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java (-1 / +8 lines)
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
11
 *     							bug 328281 - visibility leaks not detected when analyzing unused field in private class
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
14
package org.eclipse.jdt.internal.compiler.lookup;
13
15
Lines 1063-1068 Link Here
1063
	return accessors[1];
1065
	return accessors[1];
1064
}
1066
}
1065
1067
1068
public boolean hasTypeBit(int bit) {
1069
	// source types initialize type bits during connectSuperclass/interfaces()
1070
	return (this.typeBits & bit) != 0;
1071
}
1072
1066
/**
1073
/**
1067
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
1074
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
1068
 */
1075
 */
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java (+3 lines)
Lines 7-12 Link Here
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 123-128 Link Here
123
	char[][] JAVA_LANG_ANNOTATION_ELEMENTTYPE = {JAVA, LANG, ANNOTATION, "ElementType".toCharArray()}; //$NON-NLS-1$
124
	char[][] JAVA_LANG_ANNOTATION_ELEMENTTYPE = {JAVA, LANG, ANNOTATION, "ElementType".toCharArray()}; //$NON-NLS-1$
124
	char[][] JAVA_LANG_REFLECT_FIELD = new char[][] {JAVA, LANG, REFLECT, "Field".toCharArray()}; //$NON-NLS-1$
125
	char[][] JAVA_LANG_REFLECT_FIELD = new char[][] {JAVA, LANG, REFLECT, "Field".toCharArray()}; //$NON-NLS-1$
125
	char[][] JAVA_LANG_REFLECT_METHOD = new char[][] {JAVA, LANG, REFLECT, "Method".toCharArray()}; //$NON-NLS-1$
126
	char[][] JAVA_LANG_REFLECT_METHOD = new char[][] {JAVA, LANG, REFLECT, "Method".toCharArray()}; //$NON-NLS-1$
127
	char[][] JAVA_IO_CLOSEABLE = new char[][] { JAVA, IO, "Closeable".toCharArray()};//$NON-NLS-1$
126
	char[][] JAVA_IO_OBJECTSTREAMEXCEPTION = new char[][] { JAVA, IO, "ObjectStreamException".toCharArray()};//$NON-NLS-1$
128
	char[][] JAVA_IO_OBJECTSTREAMEXCEPTION = new char[][] { JAVA, IO, "ObjectStreamException".toCharArray()};//$NON-NLS-1$
127
	char[][] JAVA_IO_EXTERNALIZABLE = {JAVA, IO, "Externalizable".toCharArray()}; //$NON-NLS-1$
129
	char[][] JAVA_IO_EXTERNALIZABLE = {JAVA, IO, "Externalizable".toCharArray()}; //$NON-NLS-1$
128
	char[][] JAVA_IO_IOEXCEPTION = new char[][] { JAVA, IO, "IOException".toCharArray()};//$NON-NLS-1$
130
	char[][] JAVA_IO_IOEXCEPTION = new char[][] { JAVA, IO, "IOException".toCharArray()};//$NON-NLS-1$
Lines 151-156 Link Here
151
			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
153
			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
152
	};
154
	};
153
	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
155
	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
156
	char[] CLOSE = "close".toCharArray(); //$NON-NLS-1$
154
157
155
	// Constraints for generic type argument inference
158
	// Constraints for generic type argument inference
156
	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
159
	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java (+12 lines)
Lines 7-12 Link Here
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 182-185 Link Here
182
	final int Object2boolean = T_JavaLangObject + (T_boolean << 4);
183
	final int Object2boolean = T_JavaLangObject + (T_boolean << 4);
183
	final int BOXING = 0x200;
184
	final int BOXING = 0x200;
184
	final int UNBOXING = 0x400;
185
	final int UNBOXING = 0x400;
186
187
	/** 
188
	 * Marks all sub-types of java.lang.AutoCloseable.
189
	 * @see ReferenceBinding#hasTypeBit(int)
190
	 */
191
	final int BitAutoCloseable = 1;
192
	/** 
193
	 * Marks all sub-types of java.io.Closeable.
194
	 * @see ReferenceBinding#hasTypeBit(int)
195
	 */
196
	final int BitCloseable = 2;
185
}
197
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java (-2 / +18 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-13 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
10
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
11
 *     							bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.lookup;
14
package org.eclipse.jdt.internal.compiler.lookup;
13
15
Lines 42-47 Link Here
42
		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
44
		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
43
		this.tagBits |= TagBits.HasTypeVariable;
45
		this.tagBits |= TagBits.HasTypeVariable;
44
		this.environment = environment;
46
		this.environment = environment;
47
		this.typeBits = -1;
45
	}
48
	}
46
49
47
	/**
50
	/**
Lines 307-312 Link Here
307
		return true;
310
		return true;
308
	}
311
	}
309
312
313
	public boolean hasTypeBit(int bit) {
314
		if (this.typeBits == -1) {
315
			// initialize from bounds
316
			this.typeBits = 0;
317
			if (this.superclass != null)
318
				this.typeBits |= this.superclass.typeBits;
319
			if (this.superInterfaces != null)
320
				for (int i = 0, l = this.superInterfaces.length; i < l; i++)
321
					this.typeBits |= this.superInterfaces[i].typeBits;
322
		}
323
		return (this.typeBits & bit) != 0;
324
	}
325
310
	/**
326
	/**
311
	 * Returns true if the type variable is directly bound to a given type
327
	 * Returns true if the type variable is directly bound to a given type
312
	 */
328
	 */
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java (-1 / +6 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 41-46 Link Here
41
public String debugName() {
42
public String debugName() {
42
	return toString();
43
	return toString();
43
}
44
}
45
public boolean hasTypeBit(int bit) {
46
	// shouldn't happen since we are not called before analyseCode(), but play safe:
47
	return false;
48
}
44
ReferenceBinding resolve(LookupEnvironment environment, boolean convertGenericToRawType) {
49
ReferenceBinding resolve(LookupEnvironment environment, boolean convertGenericToRawType) {
45
    ReferenceBinding targetType = this.resolvedType;
50
    ReferenceBinding targetType = this.resolvedType;
46
	if (targetType == null) {
51
	if (targetType == null) {
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java (-1 / +16 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
2
 * Copyright (c) 2005, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 54-59 Link Here
54
		if (bound instanceof UnresolvedReferenceBinding)
55
		if (bound instanceof UnresolvedReferenceBinding)
55
			((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
56
			((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
56
		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
57
		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
58
		this.typeBits = -1;
57
	}
59
	}
58
60
59
	public int kind() {
61
	public int kind() {
Lines 420-425 Link Here
420
		return this.genericType.hashCode();
422
		return this.genericType.hashCode();
421
	}
423
	}
422
424
425
	public boolean hasTypeBit(int bit) {
426
		if (this.typeBits == -1) {
427
			// initialize from upper bounds
428
			this.typeBits = 0;
429
			if (this.superclass != null)
430
				this.typeBits |= this.superclass.typeBits;
431
			if (this.superInterfaces != null)
432
				for (int i = 0, l = this.superInterfaces.length; i < l; i++)
433
					this.typeBits |= this.superInterfaces[i].typeBits;
434
		}
435
		return (this.typeBits & bit) != 0;
436
	}
437
423
	void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
438
	void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
424
		this.genericType = someGenericType;
439
		this.genericType = someGenericType;
425
		this.bound = someBound;
440
		this.bound = someBound;
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (+59 lines)
Lines 11-16 Link Here
11
 *     Stephan Herrmann  - Contributions for 
11
 *     Stephan Herrmann  - Contributions for 
12
 *     						bug 236385 - 
12
 *     						bug 236385 - 
13
 *     						bug 338303 - Warning about Redundant assignment conflicts with definite assignment
13
 *     						bug 338303 - Warning about Redundant assignment conflicts with definite assignment
14
 *     						bug 349326 - [1.7] new warning for missing try-with-resources
14
 *******************************************************************************/
15
 *******************************************************************************/
15
package org.eclipse.jdt.internal.compiler.problem;
16
package org.eclipse.jdt.internal.compiler.problem;
16
17
Lines 51-56 Link Here
51
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
52
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
52
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
53
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
53
import org.eclipse.jdt.internal.compiler.ast.Expression;
54
import org.eclipse.jdt.internal.compiler.ast.Expression;
55
import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
54
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
56
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
55
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
57
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
56
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
58
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
Lines 426-431 Link Here
426
			
428
			
427
		case IProblem.MethodCanBePotentiallyStatic:
429
		case IProblem.MethodCanBePotentiallyStatic:
428
			return CompilerOptions.MethodCanBePotentiallyStatic;
430
			return CompilerOptions.MethodCanBePotentiallyStatic;
431
432
		case IProblem.UnclosedCloseable:
433
		case IProblem.UnclosedCloseableAtExit:
434
			return CompilerOptions.UnclosedCloseable;
435
		case IProblem.PotentiallyUnclosedCloseable:
436
		case IProblem.PotentiallyUnclosedCloseableAtExit:
437
			return CompilerOptions.PotentiallyUnclosedCloseable;
438
		case IProblem.ExplicitlyClosedAutoCloseable:
439
			return CompilerOptions.ExplicitlyClosedAutoCloseable;
429
				
440
				
430
		case IProblem.RedundantSpecificationOfTypeArguments:
441
		case IProblem.RedundantSpecificationOfTypeArguments:
431
			return CompilerOptions.RedundantSpecificationOfTypeArguments;
442
			return CompilerOptions.RedundantSpecificationOfTypeArguments;
Lines 461-466 Link Here
461
			case CompilerOptions.ParameterAssignment :
472
			case CompilerOptions.ParameterAssignment :
462
			case CompilerOptions.MethodCanBeStatic :
473
			case CompilerOptions.MethodCanBeStatic :
463
			case CompilerOptions.MethodCanBePotentiallyStatic :
474
			case CompilerOptions.MethodCanBePotentiallyStatic :
475
			case CompilerOptions.ExplicitlyClosedAutoCloseable :
464
				return CategorizedProblem.CAT_CODE_STYLE;
476
				return CategorizedProblem.CAT_CODE_STYLE;
465
477
466
			case CompilerOptions.MaskedCatchBlock :
478
			case CompilerOptions.MaskedCatchBlock :
Lines 482-487 Link Here
482
			case CompilerOptions.ShouldImplementHashcode :
494
			case CompilerOptions.ShouldImplementHashcode :
483
			case CompilerOptions.DeadCode :
495
			case CompilerOptions.DeadCode :
484
			case CompilerOptions.UnusedObjectAllocation :
496
			case CompilerOptions.UnusedObjectAllocation :
497
			case CompilerOptions.UnclosedCloseable :
498
			case CompilerOptions.PotentiallyUnclosedCloseable :
485
				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
499
				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
486
			
500
			
487
			case CompilerOptions.OverriddenPackageDefaultMethod :
501
			case CompilerOptions.OverriddenPackageDefaultMethod :
Lines 7931-7934 Link Here
7931
			location.sourceEnd);
7945
			location.sourceEnd);
7932
    }
7946
    }
7933
}
7947
}
7948
public void potentiallyUnclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
7949
	String[] args = { String.valueOf(trackVar.name) };
7950
	if (location == null) {
7951
		this.handle(
7952
			IProblem.PotentiallyUnclosedCloseable,
7953
			args,
7954
			args,
7955
			trackVar.sourceStart,
7956
			trackVar.sourceEnd);
7957
	} else {
7958
		this.handle(
7959
			IProblem.PotentiallyUnclosedCloseableAtExit,
7960
			args,
7961
			args,
7962
			location.sourceStart,
7963
			location.sourceEnd);
7964
	}
7965
}
7966
public void unclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
7967
	String[] args = { String.valueOf(trackVar.name) };
7968
	if (location == null) {
7969
		this.handle(
7970
			IProblem.UnclosedCloseable,
7971
			args,
7972
			args,
7973
			trackVar.sourceStart,
7974
			trackVar.sourceEnd);
7975
	} else {
7976
		this.handle(
7977
			IProblem.UnclosedCloseableAtExit,
7978
			args,
7979
			args,
7980
			location.sourceStart,
7981
			location.sourceEnd);
7982
	}
7983
}
7984
public void explicitlyClosedAutoCloseable(FakedTrackingVariable trackVar) {
7985
	String[] args = { String.valueOf(trackVar.name) };
7986
	this.handle(
7987
		IProblem.ExplicitlyClosedAutoCloseable,
7988
		args,
7989
		args,
7990
		trackVar.sourceStart,
7991
		trackVar.sourceEnd);	
7992
}
7934
}
7993
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties (-1 / +8 lines)
Lines 8-14 Link Here
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
#		Benjamin Muskalla - Contribution for bug 239066
10
#		Benjamin Muskalla - Contribution for bug 239066
11
#		Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
11
#		Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
12
#							bug 185682 - Increment/decrement operators mark local variables as read
13
#							bug 349326 - [1.7] new warning for missing try-with-resources
12
###############################################################################
14
###############################################################################
13
0 = {0}
15
0 = {0}
14
1 = super cannot be used in java.lang.Object
16
1 = super cannot be used in java.lang.Object
Lines 644-649 Link Here
644
882 = Unhandled exception type {0} thrown by automatic close() invocation on {1}
646
882 = Unhandled exception type {0} thrown by automatic close() invocation on {1}
645
883 = '<>' operator is not allowed for source level below 1.7
647
883 = '<>' operator is not allowed for source level below 1.7
646
884 = Redundant specification of type arguments <{0}>
648
884 = Redundant specification of type arguments <{0}>
649
885 = Potential resource leak: '{0}' may not be closed
650
886 = Potential resource leak: '{0}' may not be closed at this location
651
887 = Resource leak: '{0}' is never closed
652
888 = Resource leak: '{0}' is not closed at this location
653
889 = Resource '{0}' should be managed by try-with-resource
647
654
648
### ELABORATIONS
655
### ELABORATIONS
649
## Access restrictions
656
## Access restrictions
(-)a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java (-2 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 867-873 Link Here
867
867
868
	/**
868
	/**
869
	 * Enables the recording of changes to this compilation
869
	 * Enables the recording of changes to this compilation
870
	 * unit and its descendents. The compilation unit must have
870
	 * unit and its descendants. The compilation unit must have
871
	 * been created by <code>ASTParser</code> and still be in
871
	 * been created by <code>ASTParser</code> and still be in
872
	 * its original state. Once recording is on,
872
	 * its original state. Once recording is on,
873
	 * arbitrary changes to the subtree rooted at this compilation
873
	 * arbitrary changes to the subtree rooted at this compilation
(-)a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java (+50 lines)
Lines 83-88 Link Here
83
 *     Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD
83
 *     Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD
84
 *     Stephan Herrmann  - added COMPILER_PB_UNUSED_OBJECT_ALLOCATION
84
 *     Stephan Herrmann  - added COMPILER_PB_UNUSED_OBJECT_ALLOCATION
85
 *     Stephan Herrmann  - added COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS
85
 *     Stephan Herrmann  - added COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS
86
 *     Stephan Herrmann  - added the following constants:
87
 *     								COMPILER_PB_UNCLOSED_CLOSEABLE,
88
 *     								COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE
89
 *     								COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE
86
 *******************************************************************************/
90
 *******************************************************************************/
87
91
88
package org.eclipse.jdt.core;
92
package org.eclipse.jdt.core;
Lines 1357-1362 Link Here
1357
	 */
1361
	 */
1358
	public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
1362
	public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
1359
	/**
1363
	/**
1364
	 * Compiler option ID: Reporting a resource that is not closed properly.
1365
	 * <p>When enabled, that compiler will issue an error or a warning if
1366
	 *    a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) 
1367
	 *    or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if
1368
	 *    flow analysis shows that the method <code>close()</code> is not invoked locally on that value.
1369
	 * <dl>
1370
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code></dd>
1371
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1372
	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
1373
	 * </dl>
1374
	 * @since 3.8
1375
	 * @category CompilerOptionID
1376
	 */
1377
	public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$
1378
	/**
1379
	 * Compiler option ID: Reporting a resource that may not be closed properly.
1380
	 * <p>When enabled, that compiler will issue an error or a warning if
1381
	 *    a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) 
1382
	 *    or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if
1383
	 *    flow analysis shows that the method <code>close()</code> is 
1384
	 *    not invoked locally on that value for all execution paths.
1385
	 * <dl>
1386
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
1387
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1388
	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
1389
	 * </dl>
1390
	 * @since 3.8
1391
	 * @category CompilerOptionID
1392
	 */
1393
	public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
1394
	/**
1395
	 * Compiler option ID: Reporting a resource that is not managed by try-with-resources.
1396
	 * <p>When enabled, that compiler will issue an error or a warning if a local variable 
1397
	 * 	  holds a value of type <code>java.lang.AutoCloseable</code>, and if the method
1398
	 *    <code>close()</code> is explicitly invoked on that resource, but the resource is
1399
	 *    not managed by a try-with-resources block.
1400
	 * <dl>
1401
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
1402
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1403
	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
1404
	 * </dl>
1405
	 * @since 3.8
1406
	 * @category CompilerOptionID
1407
	 */
1408
	public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
1409
	/**
1360
	 * Compiler option ID: Setting Source Compatibility Mode.
1410
	 * Compiler option ID: Setting Source Compatibility Mode.
1361
	 * <p>Specify whether which source level compatibility is used. From 1.4 on, <code>'assert'</code> is a keyword
1411
	 * <p>Specify whether which source level compatibility is used. From 1.4 on, <code>'assert'</code> is a keyword
1362
	 *    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
1412
	 *    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM

Return to bug 349326