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

Collapse All | Expand All

(-)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
	 */
(-)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.markPotentialClosing(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)
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (+22 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 trackerBinding = null;
53
		if (local.closeTracker != null) {
54
			// Assigning to a variable already holding an AutoCloseable, has it been closed before?
55
			trackerBinding = local.closeTracker.binding;
56
			if (!flowInfo.isDefinitelyNull(local)) { // only if previous value may be non-null
57
				local.closeTracker.recordErrorLocation(this, flowInfo.nullStatus(trackerBinding));
58
			}
59
		}
60
		if (FakedTrackingVariable.isAutoCloseable(this.expression.resolvedType)) {
61
			// new value is AutoCloseable, start tracking, possibly re-using existing tracker var:
62
			if (trackerBinding == null) {
63
				local.closeTracker = new FakedTrackingVariable(local, this);
64
				trackerBinding = local.closeTracker.binding;
65
			}
66
			flowInfo.markAsDefinitelyNull(trackerBinding);
67
// TODO(stephan): this might be useful, but I could not find a test case for it: 
68
//				if (flowContext.initsOnFinally != null)
69
//					flowContext.initsOnFinally.markAsDefinitelyNonNull(trackerBinding);
70
		}
71
	}
50
	int nullStatus = this.expression.nullStatus(flowInfo);
72
	int nullStatus = this.expression.nullStatus(flowInfo);
51
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
73
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
52
		if (nullStatus == FlowInfo.NULL) {
74
		if (nullStatus == FlowInfo.NULL) {
(-)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
/**
(-)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);
(-)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
			}
(-)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){
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java (+166 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.FlowInfo;
21
import org.eclipse.jdt.internal.compiler.impl.Constant;
22
import org.eclipse.jdt.internal.compiler.lookup.Binding;
23
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
24
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
25
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
26
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
27
import org.eclipse.jdt.internal.compiler.lookup.Scope;
28
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
29
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
30
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
31
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
32
33
/**
34
 * A faked local variable declaration used for keeping track of data flows of a
35
 * special variable. Certain events will be recorded by changing the null info
36
 * for this variable.
37
 * 
38
 * See bug 349326 - [1.7] new warning for missing try-with-resources
39
 */
40
public class FakedTrackingVariable extends LocalDeclaration {
41
42
	/** 
43
	 * If close() is invoked from a nested method (inside a local type) 
44
	 * report remaining problems only as potential.
45
	 */
46
	public boolean closedInNestedMethod; 
47
48
	MethodScope methodScope; // designates the method declaring this variable
49
	
50
	public LocalVariableBinding originalBinding; // the real local being tracked
51
	
52
	HashMap recordedLocations; // initially null, ASTNode -> Integer 
53
54
	public FakedTrackingVariable(LocalVariableBinding original, Statement location) {
55
		super(original.name, location.sourceStart, location.sourceEnd);
56
		this.type = new SingleTypeReference(
57
				TypeConstants.OBJECT,
58
				((long)this.sourceStart <<32)+this.sourceEnd);
59
		this.methodScope = original.declaringScope.methodScope();
60
		this.originalBinding = original;
61
		resolve(original.declaringScope);
62
	}
63
	
64
	public void generateCode(BlockScope currentScope, CodeStream codeStream)
65
	{ /* NOP - this variable is completely dummy, ie. for analysis only. */ }
66
67
	public void resolve (BlockScope scope) {
68
		// only need the binding, which is used as reference in FlowInfo methods.
69
		this.binding = new LocalVariableBinding(
70
				this.name,
71
				scope.getJavaLangObject(),  // dummy, just needs to be a reference type
72
				0,
73
				false);
74
		this.binding.setConstant(Constant.NotAConstant);
75
		this.binding.useFlag = LocalVariableBinding.USED;
76
		// use a free slot without assigning it:
77
		this.binding.id = scope.registerTrackingVariable(this);
78
	}
79
80
	/**
81
	 * If expression resolves to a local variable binding of type AutoCloseable,
82
	 * answer the variable that tracks closing of that local, creating it if needed.
83
	 * @param expression
84
	 * @return a new {@link FakedTrackingVariable} or null.
85
	 */
86
	public static FakedTrackingVariable getCloseTrackingVariable(Expression expression) {
87
		if (expression instanceof SingleNameReference) {
88
			SingleNameReference name = (SingleNameReference) expression;
89
			if (name.binding instanceof LocalVariableBinding) {
90
				LocalVariableBinding local = (LocalVariableBinding)name.binding;
91
				if (local.closeTracker != null)
92
					return local.closeTracker;
93
				if (local.isParameter() || !isAutoCloseable(expression.resolvedType))
94
					return null;
95
				// tracking var doesn't yet exist. This happens in finally block
96
				// which is analyzed before the corresponding try block
97
				Statement location = local.declaration;
98
				return local.closeTracker = new FakedTrackingVariable(local, location);
99
			}
100
		}
101
		return null;
102
	}
103
104
	/** if 'invocationSite' is a call to close() that has a registered tracking variable, answer that variable's binding. */
105
	public static LocalVariableBinding getTrackerForCloseCall(ASTNode invocationSite) {
106
		if (invocationSite instanceof MessageSend) {
107
			MessageSend send = (MessageSend) invocationSite;
108
			if (CharOperation.equals(TypeConstants.CLOSE, send.selector) && send.receiver instanceof SingleNameReference) {
109
				Binding receiverBinding = ((SingleNameReference)send.receiver).binding;
110
				if (receiverBinding instanceof LocalVariableBinding) {
111
					FakedTrackingVariable trackingVariable = ((LocalVariableBinding)receiverBinding).closeTracker;
112
					if (trackingVariable != null)
113
						return trackingVariable.binding;
114
				}
115
			}
116
		}
117
		return null;
118
	}
119
120
	public static FlowInfo markPotentialClosing(Expression expression, FlowInfo flowInfo) {
121
		FakedTrackingVariable trackVar = getCloseTrackingVariable(expression);
122
		if (trackVar != null) {
123
			// insert info that the tracked resource *may* be closed (by the target method, i.e.)
124
			FlowInfo infoResourceIsClosed = flowInfo.copy();
125
			infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding);
126
			return FlowInfo.conditional(flowInfo, infoResourceIsClosed);
127
		}
128
		return flowInfo;
129
	}
130
131
	/** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */
132
	public static boolean isAutoCloseable(TypeBinding typeBinding) {
133
		return typeBinding instanceof ReferenceBinding
134
			&& ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable);
135
	}
136
	
137
	public void recordErrorLocation(ASTNode location, int nullStatus) {
138
		if (this.recordedLocations == null)
139
			this.recordedLocations = new HashMap();
140
		this.recordedLocations.put(location, new Integer(nullStatus));
141
	}
142
143
	public boolean reportRecordedErrors(Scope scope) {
144
		boolean hasReported = false;
145
		if (this.recordedLocations != null) {
146
			Iterator locations = this.recordedLocations.entrySet().iterator();
147
			while (locations.hasNext()) {
148
				Map.Entry entry = (Entry) locations.next();
149
				reportError(scope.problemReporter(), (ASTNode)entry.getKey(), ((Integer)entry.getValue()).intValue());
150
				hasReported = true;
151
			}
152
		}
153
		return hasReported;
154
	}
155
	
156
	public void reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) {
157
		if (nullStatus == FlowInfo.NULL) {
158
			if (this.closedInNestedMethod)
159
				problemReporter.potentiallyUnclosedCloseable(this, location);
160
			else
161
				problemReporter.unclosedCloseable(this, location);
162
		} else if (nullStatus == FlowInfo.POTENTIALLY_NULL) {
163
			problemReporter.potentiallyUnclosedCloseable(this, location);
164
		}		
165
	}
166
}
(-)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
(-)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
(-)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,
(-)compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (+8 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
	if (FakedTrackingVariable.isAutoCloseable(this.initialization.resolvedType)) {
81
		this.binding.closeTracker = new FakedTrackingVariable(this.binding, this);
82
		flowInfo.markAsDefinitelyNull(this.binding.closeTracker.binding);
83
// TODO(stephan): this might be useful, but I could not find a test case for it: 
84
//		if (flowContext.initsOnFinally != null)
85
//			flowContext.initsOnFinally.markAsDefinitelyNonNull(this.binding.closeTracker.binding);
86
	}
79
	int nullStatus = this.initialization.nullStatus(flowInfo);
87
	int nullStatus = this.initialization.nullStatus(flowInfo);
80
	if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
88
	if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
81
		this.bits |= FirstAssignmentToLocal;
89
		this.bits |= FirstAssignmentToLocal;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-1 / +21 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
				flowInfo.markAsDefinitelyNonNull(trackingVariable.binding);
73
// TODO(stephan): this might be useful, but I could not find a test case for it: 
74
//				if (flowContext.initsOnFinally != null)
75
//					flowContext.initsOnFinally.markAsDefinitelyNonNull(trackingVariable.binding);
76
			} else {
77
				trackingVariable.closedInNestedMethod = true;
78
			}
79
		}
80
	}
63
	if (nonStatic) {
81
	if (nonStatic) {
64
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
82
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
65
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
83
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
Lines 80-85 Link Here
80
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
98
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
81
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
99
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
82
			}
100
			}
101
			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
102
			flowInfo = FakedTrackingVariable.markPotentialClosing(this.arguments[i], flowInfo);
83
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
103
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
84
		}
104
		}
85
	}
105
	}
(-)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
		}
(-)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.markPotentialClosing(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);
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (-1 / +10 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 40-45 Link Here
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);
42
		}
44
		}
45
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
46
		if (trackingVariable != null) {
47
			// don't report issues concerning this local, since by returning
48
			// the method passes the responsibility to the caller:
49
			currentScope.removeTrackingVar(trackingVariable);
50
		}
43
	}
51
	}
44
	this.initStateIndex =
52
	this.initStateIndex =
45
		currentScope.methodScope().recordInitializationStates(flowInfo);
53
		currentScope.methodScope().recordInitializationStates(flowInfo);
Lines 104-109 Link Here
104
			this.expression.bits |= ASTNode.IsReturnedValue;
112
			this.expression.bits |= ASTNode.IsReturnedValue;
105
		}
113
		}
106
	}
114
	}
115
	currentScope.checkUnclosedCloseables(flowInfo, null/*ignore exception exits from flowContext*/, this);
107
	return FlowInfo.DEAD_END;
116
	return FlowInfo.DEAD_END;
108
}
117
}
109
118
(-)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
		}
(-)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;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java (-5 / +19 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 332637 - Dead Code detection removing code that isn't dead
10
 *     Stephan Herrmann - Contributions for
11
 *     							bug 332637 - Dead Code detection removing code that isn't dead
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 124-131 Link Here
124
		for (int i = 0; i < resourcesLength; i++) {
126
		for (int i = 0; i < resourcesLength; i++) {
125
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
127
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
126
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
128
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
127
			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
129
			LocalVariableBinding resourceBinding = this.resources[i].binding;
128
			TypeBinding type = this.resources[i].binding.type;
130
			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
131
			if (resourceBinding.closeTracker != null) {
132
				// this was false alarm, we don't need to track the resource
133
				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
134
				resourceBinding.closeTracker = null;
135
			} 
136
			TypeBinding type = resourceBinding.type;
129
			if (type != null && type.isValidBinding()) {
137
			if (type != null && type.isValidBinding()) {
130
				ReferenceBinding binding = (ReferenceBinding) type;
138
				ReferenceBinding binding = (ReferenceBinding) type;
131
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
139
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
Lines 250-257 Link Here
250
		for (int i = 0; i < resourcesLength; i++) {
258
		for (int i = 0; i < resourcesLength; i++) {
251
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
259
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
252
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
260
			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
253
			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
261
			LocalVariableBinding resourceBinding = this.resources[i].binding;
254
			TypeBinding type = this.resources[i].binding.type;
262
			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
263
			if (resourceBinding.closeTracker != null) {
264
				// this was false alarm, we don't need to track the resource
265
				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
266
				resourceBinding.closeTracker = null;
267
			} 
268
			TypeBinding type = resourceBinding.type;
255
			if (type != null && type.isValidBinding()) {
269
			if (type != null && type.isValidBinding()) {
256
				ReferenceBinding binding = (ReferenceBinding) type;
270
				ReferenceBinding binding = (ReferenceBinding) type;
257
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
271
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
(-)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
(-)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]
(-)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
	
(-)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);
(-)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;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (+142 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;
12
13
14
import java.util.ArrayList;
15
import java.util.List;
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) return;
993
	if (location != null && flowInfo.reachMode() != 0) return;
994
	for (int i=0; i<this.trackingVariables.size(); i++) {
995
		FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
996
		if (location != null && trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding))
997
			continue; // reporting against a specific location, resource is null at this flow, don't complain
998
		int status = getNullStatusAggressively(trackingVar.binding, flowInfo);
999
		if (status == FlowInfo.NULL) {
1000
			// definitely unclosed: highest priority
1001
			reportResourceLeak(trackingVar, location, status);
1002
			if (location == null) {
1003
				// definitely done with this trackingVar, remove it
1004
				this.trackingVariables.remove(trackingVar);
1005
				i--; // ... but don't disturb the enclosing loop.
1006
			}
1007
			continue;
1008
		}
1009
		if (location == null) // at end of block an not definitely unclosed
1010
		{
1011
			// problems at specific locations: medium priority
1012
			if (trackingVar.reportRecordedErrors(this)) // ... report previously recorded errors
1013
				continue;
1014
		} 
1015
		if (status == FlowInfo.POTENTIALLY_NULL) {
1016
			// potentially unclosed: lower priority
1017
			reportResourceLeak(trackingVar, location, status);
1018
		} else if (status == FlowInfo.NON_NULL) {
1019
			// properly closed but not managed by t-w-r: lowest priority 
1020
			if (environment().globalOptions.complianceLevel >= ClassFileConstants.JDK1_7) 
1021
				problemReporter().explicitlyClosedAutoCloseable(trackingVar);
1022
		}
1023
	}
1024
}
1025
private void reportResourceLeak(FakedTrackingVariable trackingVar, ASTNode location, int nullStatus) {
1026
	if (location != null)
1027
		trackingVar.recordErrorLocation(location, nullStatus);
1028
	else
1029
		trackingVar.reportError(problemReporter(), null, nullStatus);
1030
}
1031
1032
/** 
1033
 * If one branch of an if-else closes any AutoCloseable resource, and if the same
1034
 * resource is known to be null on the other branch mark it as closed, too,
1035
 * so that merging both branches indicates that the resource is always closed.
1036
 * Example:
1037
 *	FileReader fr1 = null;
1038
 *	try {\n" +
1039
 *      fr1 = new FileReader(someFile);" + 
1040
 *		fr1.read(buf);\n" + 
1041
 *	} finally {\n" + 
1042
 *		if (fr1 != null)\n" +
1043
 *           try {\n" +
1044
 *               fr1.close();\n" +
1045
 *           } catch (IOException e) {
1046
 *              // do nothing 
1047
 *           }
1048
 *      // after this if statement fr1 is definitely not leaked 
1049
 *	}
1050
 */
1051
public void correlateTrackingVarsIfElse(FlowInfo thenFlowInfo, FlowInfo elseFlowInfo) {
1052
	if (this.trackingVariables != null) {
1053
		for (int i=0; i<this.trackingVariables.size(); i++) {
1054
			FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
1055
			if (   thenFlowInfo.isDefinitelyNonNull(trackingVar.binding)			// closed in then branch
1056
				&& elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding))		// null in else branch
1057
			{
1058
				elseFlowInfo.markAsDefinitelyNonNull(trackingVar.binding);			// -> always closed
1059
			}
1060
			else if (   elseFlowInfo.isDefinitelyNonNull(trackingVar.binding)		// closed in else branch
1061
					 && thenFlowInfo.isDefinitelyNull(trackingVar.originalBinding))	// null in then branch
1062
			{
1063
				thenFlowInfo.markAsDefinitelyNonNull(trackingVar.binding);			// -> always closed
1064
			}
1065
		}
1066
	}
1067
	if (this.parent instanceof BlockScope)
1068
		((BlockScope) this.parent).correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
1069
}
1070
1071
/**
1072
 * Get the null status looking even into unreachable flows
1073
 * @param local
1074
 * @param flowInfo
1075
 * @return one of the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}.
1076
 */
1077
private int getNullStatusAggressively(LocalVariableBinding local, FlowInfo flowInfo) {
1078
	int reachMode = flowInfo.reachMode();
1079
	int status = 0;
1080
	try {
1081
		// unreachable flowInfo is too shy in reporting null-issues, temporarily forget reachability:
1082
		if (reachMode != FlowInfo.REACHABLE)
1083
			flowInfo.tagBits &= ~FlowInfo.UNREACHABLE;
1084
		status = flowInfo.nullStatus(local);
1085
	} finally {
1086
		// reset
1087
		flowInfo.tagBits |= reachMode;
1088
	}
1089
	// at this point some combinations are not useful so flatten to a single bit:
1090
	if ((status & FlowInfo.NULL) != 0) {
1091
		if ((status & (FlowInfo.NON_NULL | FlowInfo.POTENTIALLY_NON_NULL)) != 0)
1092
			return FlowInfo.POTENTIALLY_NULL; 	// null + doubt = pot null
1093
		return FlowInfo.NULL;
1094
	} else if ((status & FlowInfo.NON_NULL) != 0) {
1095
		if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
1096
			return FlowInfo.POTENTIALLY_NULL;	// non-null + doubt = pot null
1097
		return FlowInfo.NON_NULL;
1098
	} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
1099
		return FlowInfo.POTENTIALLY_NULL;
1100
	return status;
1101
}
960
}
1102
}
(-)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
(-)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)
(-)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];
(-)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
	 */
(-)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.
(-)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.
(-)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
 */
(-)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
(-)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
}
(-)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
	 */
(-)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) {
(-)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;
(-)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
}
(-)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
(-)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 AutoCloseable and if
1367
	 *    flow analysis shows that the method <code>close()</code> is not invoked locally on that value.
1368
	 * <dl>
1369
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code></dd>
1370
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1371
	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
1372
	 * </dl>
1373
	 * @since 3.8
1374
	 * @category CompilerOptionID
1375
	 */
1376
	public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$
1377
	/**
1378
	 * Compiler option ID: Reporting a resource that may not be closed properly.
1379
	 * <p>When enabled, that compiler will issue an error or a warning if
1380
	 *    a local variable holds a value of type AutoCloseable and if
1381
	 *    flow analysis shows that the method <code>close()</code> is 
1382
	 *    not invoked locally on that value for all execution paths.
1383
	 * <dl>
1384
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
1385
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1386
	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
1387
	 * </dl>
1388
	 * @since 3.8
1389
	 * @category CompilerOptionID
1390
	 */
1391
	public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
1392
	/**
1393
	 * Compiler option ID: Reporting a resource that is not managed by try-with-resources.
1394
	 * <p>When enabled, that compiler will issue an error or a warning if a local variable 
1395
	 * 	  holds a value of type AutoCloseable, and if the method <code>close()</code> is
1396
	 * 	  explicitly invoked on that resource, but the resource is not managed by a
1397
	 * 	  try-with-resources block.
1398
	 * <p>Note that this option is not intended to be surfaced in the UI, as it is intended
1399
	 *    only for internal use for computing quick assists / cleanups. 
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
(-)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" + 
(-)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);
(-)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
}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java (-5 / +1195 lines)
Lines 7-24 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.core.tests.compiler.regression;
12
package org.eclipse.jdt.core.tests.compiler.regression;
12
13
13
import java.util.Map;
14
import java.util.Map;
14
15
16
import org.eclipse.jdt.core.JavaCore;
15
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
17
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
16
18
17
import junit.framework.Test;
19
import junit.framework.Test;
18
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
20
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
19
21
20
static {
22
static {
21
//	TESTS_NAMES = new String[] { "test055", "test055a" };
23
//	TESTS_NAMES = new String[] { "test056u" };
22
//	TESTS_NUMBERS = new int[] { 50 };
24
//	TESTS_NUMBERS = new int[] { 50 };
23
//	TESTS_RANGE = new int[] { 11, -1 };
25
//	TESTS_RANGE = new int[] { 11, -1 };
24
}
26
}
Lines 485-496 Link Here
485
		"	               ^^\n" + 
487
		"	               ^^\n" + 
486
		"Dead code\n" + 
488
		"Dead code\n" + 
487
		"----------\n" + 
489
		"----------\n" + 
488
		"3. ERROR in X.java (at line 5)\n" + 
490
		"3. WARNING in X.java (at line 5)\n" + 
491
		"	Y why = new Y();\n" + 
492
		"	  ^^^\n" + 
493
		"Resource leak: 'why' is never closed\n" + 
494
		"----------\n" + 
495
		"4. ERROR in X.java (at line 5)\n" + 
489
		"	Y why = new Y();\n" + 
496
		"	Y why = new Y();\n" + 
490
		"	        ^^^^^^^\n" + 
497
		"	        ^^^^^^^\n" + 
491
		"Unhandled exception type WeirdException\n" + 
498
		"Unhandled exception type WeirdException\n" + 
492
		"----------\n" + 
499
		"----------\n" + 
493
		"4. WARNING in X.java (at line 22)\n" + 
500
		"5. WARNING in X.java (at line 22)\n" + 
494
		"	class WeirdException extends Throwable {}\n" + 
501
		"	class WeirdException extends Throwable {}\n" + 
495
		"	      ^^^^^^^^^^^^^^\n" + 
502
		"	      ^^^^^^^^^^^^^^\n" + 
496
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
503
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
Lines 558-569 Link Here
558
		"	               ^^\n" + 
565
		"	               ^^\n" + 
559
		"Dead code\n" + 
566
		"Dead code\n" + 
560
		"----------\n" + 
567
		"----------\n" + 
561
		"3. ERROR in X.java (at line 5)\n" + 
568
		"3. WARNING in X.java (at line 5)\n" + 
569
		"	Y why = new Y();\n" + 
570
		"	  ^^^\n" + 
571
		"Resource leak: 'why' is never closed\n" + 
572
		"----------\n" + 
573
		"4. ERROR in X.java (at line 5)\n" + 
562
		"	Y why = new Y();\n" + 
574
		"	Y why = new Y();\n" + 
563
		"	        ^^^^^^^\n" + 
575
		"	        ^^^^^^^\n" + 
564
		"Unhandled exception type WeirdException\n" + 
576
		"Unhandled exception type WeirdException\n" + 
565
		"----------\n" + 
577
		"----------\n" + 
566
		"4. WARNING in X.java (at line 20)\n" + 
578
		"5. WARNING in X.java (at line 20)\n" + 
567
		"	class WeirdException extends Throwable {}\n" + 
579
		"	class WeirdException extends Throwable {}\n" + 
568
		"	      ^^^^^^^^^^^^^^\n" + 
580
		"	      ^^^^^^^^^^^^^^\n" + 
569
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
581
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
Lines 3380-3385 Link Here
3380
		},
3392
		},
3381
		"Done");
3393
		"Done");
3382
}
3394
}
3395
// Bug 349326 - [1.7] new warning for missing try-with-resources
3396
// a method uses an AutoCloseable without ever closing it.
3397
public void test056() {
3398
	Map options = getCompilerOptions();
3399
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3400
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3401
	this.runNegativeTest(
3402
		new String[] {
3403
			"X.java",
3404
			"import java.io.File;\n" +
3405
			"import java.io.FileReader;\n" +
3406
			"import java.io.IOException;\n" +
3407
			"public class X {\n" +
3408
			"    void foo() throws IOException {\n" +
3409
			"        File file = new File(\"somefile\");\n" +
3410
			"        FileReader fileReader = new FileReader(file);\n" +
3411
// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler
3412
//			"        char[] in = new char[50];\n" +
3413
//			"        fileReader.read(in);\n" +
3414
			"    }\n" +
3415
			"    public static void main(String[] args) throws IOException {\n" +
3416
			"        new X().foo();\n" +
3417
			"    }\n" +
3418
			"}\n"
3419
		},
3420
		"----------\n" + 
3421
		"1. ERROR in X.java (at line 7)\n" + 
3422
		"	FileReader fileReader = new FileReader(file);\n" + 
3423
		"	           ^^^^^^^^^^\n" + 
3424
		"Resource leak: 'fileReader' is never closed\n" +
3425
		"----------\n",
3426
		null,
3427
		true,
3428
		options);
3429
}
3430
// Bug 349326 - [1.7] new warning for missing try-with-resources
3431
// a method uses an AutoCloseable and closes it but not protected by t-w-r nor regular try-finally
3432
public void test056a() {
3433
	Map options = getCompilerOptions();
3434
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3435
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3436
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3437
	this.runNegativeTest(
3438
		new String[] {
3439
			"X.java",
3440
			"import java.io.File;\n" +
3441
			"import java.io.FileReader;\n" +
3442
			"import java.io.IOException;\n" +
3443
			"public class X {\n" +
3444
			"    void foo() throws IOException {\n" +
3445
			"        File file = new File(\"somefile\");\n" +
3446
			"        FileReader fileReader = new FileReader(file);\n" +
3447
			"        char[] in = new char[50];\n" +
3448
			"        fileReader.read(in);\n" +
3449
			"		 fileReader.close();\n" +
3450
			"    }\n" +
3451
			"    public static void main(String[] args) {\n" +
3452
			"        try {\n" +
3453
			"            new X().foo();\n" +
3454
			"        } catch (IOException ioex) {\n" +
3455
			"            System.out.println(\"caught\");\n" +
3456
			"        }\n" +
3457
			"    }\n" +
3458
			"}\n"
3459
		},
3460
		"----------\n" + 
3461
		"1. ERROR in X.java (at line 7)\n" + 
3462
		"	FileReader fileReader = new FileReader(file);\n" + 
3463
		"	           ^^^^^^^^^^\n" + 
3464
		"Resource 'fileReader' should be managed by try-with-resource\n" + 
3465
		"----------\n",
3466
		null,
3467
		true,
3468
		options);
3469
}
3470
// Bug 349326 - [1.7] new warning for missing try-with-resources
3471
// a method uses an AutoCloseable and closes it properly in a finally block
3472
public void test056b() {
3473
	Map options = getCompilerOptions();
3474
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3475
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3476
	this.runConformTest(
3477
		new String[] {
3478
			"X.java",
3479
			"import java.io.File;\n" +
3480
			"import java.io.FileReader;\n" +
3481
			"import java.io.IOException;\n" +
3482
			"public class X {\n" +
3483
			"    void foo() throws IOException {\n" +
3484
			"        File file = new File(\"somefile\");\n" +
3485
			"        FileReader fileReader = new FileReader(file);\n" +
3486
			"        try {\n" +
3487
			"            char[] in = new char[50];\n" +
3488
			"            fileReader.read(in);\n" +
3489
			"        } finally {\n" +
3490
			"		     fileReader.close();\n" +
3491
			"        }\n" +
3492
			"    }\n" +
3493
			"    public static void main(String[] args) {\n" +
3494
			"        try {\n" +
3495
			"            new X().foo();\n" +
3496
			"        } catch (IOException ioex) {\n" +
3497
			"            System.out.println(\"caught\");\n" +
3498
			"        }\n" +
3499
			"    }\n" +
3500
			"}\n"
3501
		},
3502
		"caught", /*output*/
3503
		null/*classLibs*/,
3504
		true/*shouldFlush*/,
3505
		null/*vmargs*/,
3506
		options,
3507
		null/*requestor*/);
3508
}
3509
// Bug 349326 - [1.7] new warning for missing try-with-resources
3510
// a method uses an AutoCloseable properly within try-with-resources.
3511
public void test056c() {
3512
	Map options = getCompilerOptions();
3513
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3514
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3515
	this.runConformTest(
3516
		new String[] {
3517
			"X.java",
3518
			"import java.io.File;\n" +
3519
			"import java.io.FileReader;\n" +
3520
			"import java.io.IOException;\n" +
3521
			"public class X {\n" +
3522
			"    void foo() throws IOException {\n" +
3523
			"        File file = new File(\"somefile\");\n" +
3524
			"        try (FileReader fileReader = new FileReader(file)) {\n" +
3525
			"            char[] in = new char[50];\n" +
3526
			"            fileReader.read(in);\n" +
3527
			"		 }\n" +
3528
			"    }\n" +
3529
			"    public static void main(String[] args) {\n" +
3530
			"        try {\n" +
3531
			"            new X().foo();\n" +
3532
			"        } catch (IOException ioex) {\n" +
3533
			"            System.out.println(\"caught\");\n" +
3534
			"        }\n" +
3535
			"    }\n" +
3536
			"}\n"
3537
		},
3538
		"caught", /*output*/
3539
		null/*classLibs*/,
3540
		true/*shouldFlush*/,
3541
		null/*vmargs*/,
3542
		options,
3543
		null/*requestor*/);
3544
}
3545
// Bug 349326 - [1.7] new warning for missing try-with-resources
3546
// a method uses two AutoCloseables (testing independent analysis)
3547
// - one closeable may be unclosed at a conditional return
3548
// - the other is only conditionally closed
3549
public void test056d() {
3550
	Map options = getCompilerOptions();
3551
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3552
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3553
	this.runNegativeTest(
3554
		new String[] {
3555
			"X.java",
3556
			"import java.io.File;\n" +
3557
			"import java.io.FileReader;\n" +
3558
			"import java.io.IOException;\n" +
3559
			"public class X {\n" +
3560
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3561
			"        File file = new File(\"somefile\");\n" +
3562
			"        char[] in = new char[50];\n" +
3563
			"        FileReader fileReader1 = new FileReader(file);\n" +
3564
			"        fileReader1.read(in);\n" +
3565
			"        FileReader fileReader2 = new FileReader(file);\n" +
3566
			"        fileReader2.read(in);\n" +
3567
			"        if (flag1) {\n" +
3568
			"            fileReader2.close();\n" +
3569
			"            return;\n" +
3570
			"        } else if (flag2) {\n" +
3571
			"            fileReader2.close();\n" +
3572
			"        }\n" +
3573
			"        fileReader1.close();\n" +
3574
			"    }\n" +
3575
			"    public static void main(String[] args) throws IOException {\n" +
3576
			"        new X().foo(false, true);\n" +
3577
			"    }\n" +
3578
			"}\n"
3579
		},
3580
		"----------\n" + 
3581
		"1. WARNING in X.java (at line 10)\n" + 
3582
		"	FileReader fileReader2 = new FileReader(file);\n" + 
3583
		"	           ^^^^^^^^^^^\n" + 
3584
		"Potential resource leak: 'fileReader2' may not be closed\n" +
3585
		"----------\n" + 
3586
		"2. ERROR in X.java (at line 14)\n" + 
3587
		"	return;\n" + 
3588
		"	^^^^^^^\n" + 
3589
		"Resource leak: \'fileReader1\' is not closed at this location\n" + 
3590
		"----------\n",
3591
		null,
3592
		true,
3593
		options);
3594
}
3595
//Bug 349326 - [1.7] new warning for missing try-with-resources
3596
//a method uses two AutoCloseables (testing independent analysis)
3597
//- one closeable may be unclosed at a conditional return
3598
//- the other is only conditionally closed
3599
public void test056d_suppress() {
3600
	Map options = getCompilerOptions();
3601
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3602
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3603
	options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
3604
	this.runNegativeTest(
3605
		new String[] {
3606
			"X.java",
3607
			"import java.io.File;\n" +
3608
			"import java.io.FileReader;\n" +
3609
			"import java.io.IOException;\n" +
3610
			"public class X {\n" +
3611
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3612
			"        @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" +
3613
			"        char[] in = new char[50];\n" +
3614
			"        FileReader fileReader1 = new FileReader(file);\n" +
3615
			"        fileReader1.read(in);\n" +
3616
			"        @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" +
3617
			"        fileReader2.read(in);\n" +
3618
			"        if (flag1) {\n" +
3619
			"            fileReader2.close();\n" +
3620
			"            return; // not suppressed\n" +
3621
			"        } else if (flag2) {\n" +
3622
			"            fileReader2.close();\n" +
3623
			"        }\n" +
3624
			"        fileReader1.close();\n" +
3625
			"    }\n" +
3626
			"    @SuppressWarnings(\"resource\") // useful suppress\n" +
3627
			"    void bar() throws IOException {\n" +
3628
			"        File file = new File(\"somefile\");\n" +
3629
			"        FileReader fileReader = new FileReader(file);\n" +
3630
			"        char[] in = new char[50];\n" +
3631
			"        fileReader.read(in);\n" +
3632
			"    }\n" +
3633
			"    public static void main(String[] args) throws IOException {\n" +
3634
			"        new X().foo(false, true);\n" +
3635
			"    }\n" +
3636
			"}\n"
3637
		},
3638
		"----------\n" + 
3639
		"1. WARNING in X.java (at line 6)\n" + 
3640
		"	@SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + 
3641
		"	                  ^^^^^^^^^^\n" + 
3642
		"Unnecessary @SuppressWarnings(\"resource\")\n" + 
3643
		"----------\n" + 
3644
		"2. ERROR in X.java (at line 14)\n" + 
3645
		"	return; // not suppressed\n" + 
3646
		"	^^^^^^^\n" + 
3647
		"Resource leak: \'fileReader1\' is not closed at this location\n" + 
3648
		"----------\n",
3649
		null,
3650
		true,
3651
		options);
3652
}
3653
// Bug 349326 - [1.7] new warning for missing try-with-resources
3654
// one method returns an AutoCleasble, a second method uses this object without ever closing it.
3655
public void test056e() {
3656
	Map options = getCompilerOptions();
3657
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3658
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3659
	this.runNegativeTest(
3660
		new String[] {
3661
			"X.java",
3662
			"import java.io.File;\n" +
3663
			"import java.io.FileReader;\n" +
3664
			"import java.io.IOException;\n" +
3665
			"public class X {\n" +
3666
			"    FileReader getReader(String filename) throws IOException {\n" +
3667
			"        File file = new File(\"somefile\");\n" +
3668
			"        FileReader fileReader = new FileReader(file);\n" +
3669
			"        return fileReader;\n" + 		// don't complain here, pass responsibility to caller
3670
			"    }\n" +
3671
			"    void foo() throws IOException {\n" +
3672
			"        FileReader reader = getReader(\"somefile\");\n" +
3673
			"        char[] in = new char[50];\n" +
3674
			"        reader.read(in);\n" +
3675
			"    }\n" +
3676
			"    public static void main(String[] args) throws IOException {\n" +
3677
			"        new X().foo();\n" +
3678
			"    }\n" +
3679
			"}\n"
3680
		},
3681
		"----------\n" + 
3682
		"1. ERROR in X.java (at line 11)\n" + 
3683
		"	FileReader reader = getReader(\"somefile\");\n" + 
3684
		"	           ^^^^^^\n" + 
3685
		"Resource leak: 'reader' is never closed\n" + 
3686
		"----------\n",
3687
		null,
3688
		true,
3689
		options);
3690
}
3691
// Bug 349326 - [1.7] new warning for missing try-with-resources
3692
// a method explicitly closes its AutoCloseable rather than using t-w-r
3693
public void test056f() {
3694
	Map options = getCompilerOptions();
3695
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3696
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3697
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3698
	this.runNegativeTest(
3699
		new String[] {
3700
			"X.java",
3701
			"import java.io.File;\n" +
3702
			"import java.io.FileReader;\n" +
3703
			"import java.io.IOException;\n" +
3704
			"public class X {\n" +
3705
			"    void foo() throws IOException {\n" +
3706
			"        File file = new File(\"somefile\");\n" +
3707
			"        FileReader fileReader = null;\n" +
3708
			"        try {\n" +
3709
			"            fileReader = new FileReader(file);\n" +
3710
			"            char[] in = new char[50];\n" +
3711
			"            fileReader.read(in);\n" +
3712
			"        } finally {\n" +
3713
			"            fileReader.close();\n" +
3714
			"        }\n" +
3715
			"    }\n" +
3716
			"    public static void main(String[] args) throws IOException {\n" +
3717
			"        new X().foo();\n" +
3718
			"    }\n" +
3719
			"}\n"
3720
		},
3721
		"----------\n" + 
3722
		"1. ERROR in X.java (at line 7)\n" + 
3723
		"	FileReader fileReader = null;\n" + 
3724
		"	           ^^^^^^^^^^\n" + 
3725
		"Resource \'fileReader\' should be managed by try-with-resource\n" + 
3726
		"----------\n",
3727
		null,
3728
		true,
3729
		options);
3730
}
3731
// Bug 349326 - [1.7] new warning for missing try-with-resources
3732
// an AutoCloseable local is re-assigned
3733
public void test056g() {
3734
	Map options = getCompilerOptions();
3735
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3736
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3737
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3738
	this.runNegativeTest(
3739
		new String[] {
3740
			"X.java",
3741
			"import java.io.File;\n" +
3742
			"import java.io.FileReader;\n" +
3743
			"import java.io.IOException;\n" +
3744
			"public class X {\n" +
3745
			"    void foo() throws IOException {\n" +
3746
			"        File file = new File(\"somefile\");\n" +
3747
			"        FileReader fileReader = new FileReader(file);\n" +
3748
			"        char[] in = new char[50];\n" +
3749
			"        fileReader.read(in);\n" +
3750
			"        fileReader = new FileReader(file);\n" +
3751
			"        fileReader.read(in);\n" +
3752
			"        fileReader.close();\n" +
3753
			"        fileReader = null;\n" +
3754
			"    }\n" +
3755
			"    public static void main(String[] args) throws IOException {\n" +
3756
			"        new X().foo();\n" +
3757
			"    }\n" +
3758
			"}\n"
3759
		},
3760
		"----------\n" + 
3761
		"1. ERROR in X.java (at line 10)\n" + 
3762
		"	fileReader = new FileReader(file);\n" + 
3763
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
3764
		"Resource leak: \'fileReader\' is not closed at this location\n" + 
3765
		"----------\n",
3766
		null,
3767
		true,
3768
		options);
3769
}
3770
// Bug 349326 - [1.7] new warning for missing try-with-resources
3771
// an AutoCloseable local is re-assigned after null-assigned
3772
public void test056g2() {
3773
	Map options = getCompilerOptions();
3774
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3775
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3776
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3777
	this.runNegativeTest(
3778
		new String[] {
3779
			"X.java",
3780
			"import java.io.File;\n" +
3781
			"import java.io.FileReader;\n" +
3782
			"import java.io.IOException;\n" +
3783
			"public class X {\n" +
3784
			"    void foo() throws IOException {\n" +
3785
			"        File file = new File(\"somefile\");\n" +
3786
			"        FileReader fileReader = new FileReader(file);\n" +
3787
			"        char[] in = new char[50];\n" +
3788
			"        fileReader.read(in);\n" +
3789
			"        fileReader = null;\n" +
3790
			"        fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here
3791
			"        fileReader.read(in);\n" +
3792
			"        fileReader.close();\n" +
3793
			"    }\n" +
3794
			"    public static void main(String[] args) throws IOException {\n" +
3795
			"        new X().foo();\n" +
3796
			"    }\n" +
3797
			"}\n"
3798
		},
3799
		"----------\n" + 
3800
		"1. ERROR in X.java (at line 10)\n" + 
3801
		"	fileReader = null;\n" + 
3802
		"	^^^^^^^^^^^^^^^^^\n" + 
3803
		"Resource leak: \'fileReader\' is not closed at this location\n" + 
3804
		"----------\n",
3805
		null,
3806
		true,
3807
		options);
3808
}
3809
// Bug 349326 - [1.7] new warning for missing try-with-resources
3810
// two AutoCloseables at different nesting levels (anonymous local type)
3811
public void test056h() {
3812
	Map options = getCompilerOptions();
3813
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3814
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3815
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3816
	this.runNegativeTest(
3817
		new String[] {
3818
			"X.java",
3819
			"import java.io.File;\n" +
3820
			"import java.io.FileReader;\n" +
3821
			"import java.io.IOException;\n" +
3822
			"public class X {\n" +
3823
			"    void foo() throws IOException {\n" +
3824
			"        final File file = new File(\"somefile\");\n" +
3825
			"        final FileReader fileReader = new FileReader(file);\n" +
3826
			"        char[] in = new char[50];\n" +
3827
			"        fileReader.read(in);\n" +
3828
			"        new Runnable() {\n public void run() {\n" +
3829
			"            try {\n" +
3830
			"                fileReader.close();\n" +
3831
			"                FileReader localReader = new FileReader(file);\n" +
3832
			"            } catch (IOException ex) { /* nop */ }\n" +
3833
			"        }}.run();\n" +
3834
			"    }\n" +
3835
			"    public static void main(String[] args) throws IOException {\n" +
3836
			"        new X().foo();\n" +
3837
			"    }\n" +
3838
			"}\n"
3839
		},
3840
		"----------\n" + 
3841
		"1. WARNING in X.java (at line 7)\n" + 
3842
		"	final FileReader fileReader = new FileReader(file);\n" + 
3843
		"	                 ^^^^^^^^^^\n" + 
3844
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3845
		"----------\n" + 
3846
		"2. ERROR in X.java (at line 14)\n" + 
3847
		"	FileReader localReader = new FileReader(file);\n" + 
3848
		"	           ^^^^^^^^^^^\n" + 
3849
		"Resource leak: 'localReader' is never closed\n" + 
3850
		"----------\n",
3851
		null,
3852
		true,
3853
		options);
3854
}
3855
// Bug 349326 - [1.7] new warning for missing try-with-resources
3856
// three AutoCloseables in different blocks of the same method
3857
public void test056i() {
3858
	Map options = getCompilerOptions();
3859
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3860
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3861
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3862
	this.runNegativeTest(
3863
		new String[] {
3864
			"X.java",
3865
			"import java.io.File;\n" +
3866
			"import java.io.FileReader;\n" +
3867
			"import java.io.IOException;\n" +
3868
			"public class X {\n" +
3869
			"    void foo(boolean f1, boolean f2) throws IOException {\n" +
3870
			"        File file = new File(\"somefile\");\n" +
3871
			"        if (f1) {\n" +
3872
			"            FileReader fileReader = new FileReader(file); // err: not closed\n" +
3873
			"            char[] in = new char[50];\n" +
3874
			"            fileReader.read(in);\n" +
3875
			"            while (true) {\n" +
3876
			"                 FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
3877
			"                 loopReader.close();" +
3878
			"                 break;\n" +
3879
			"            }\n" +
3880
			"        } else {\n" +
3881
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
3882
			"            if (f2)\n" +
3883
			"                fileReader.close();\n" +
3884
			"        }\n" +
3885
			"    }\n" +
3886
			"    public static void main(String[] args) throws IOException {\n" +
3887
			"        new X().foo(true, true);\n" +
3888
			"    }\n" +
3889
			"}\n"
3890
		},
3891
		"----------\n" + 
3892
		"1. ERROR in X.java (at line 8)\n" + 
3893
		"	FileReader fileReader = new FileReader(file); // err: not closed\n" + 
3894
		"	           ^^^^^^^^^^\n" + 
3895
		"Resource leak: 'fileReader' is never closed\n" + 
3896
		"----------\n" + 
3897
		"2. WARNING in X.java (at line 16)\n" + 
3898
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3899
		"	           ^^^^^^^^^^\n" + 
3900
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3901
		"----------\n",
3902
		null,
3903
		true,
3904
		options);
3905
}
3906
// Bug 349326 - [1.7] new warning for missing try-with-resources
3907
// three AutoCloseables in different blocks of the same method
3908
public void test056i2() {
3909
	Map options = getCompilerOptions();
3910
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3911
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3912
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3913
	this.runNegativeTest(
3914
		new String[] {
3915
			"X.java",
3916
			"import java.io.File;\n" + 
3917
			"import java.io.FileReader;\n" + 
3918
			"import java.io.IOException;\n" + 
3919
			"public class X {\n" +
3920
			"    void foo(boolean f1, boolean f2) throws IOException {\n" + 
3921
			"        File file = new File(\"somefile\");\n" + 
3922
			"        if (f1) {\n" + 
3923
			"            FileReader fileReader = new FileReader(file); // properly closed\n" + 
3924
			"            char[] in = new char[50];\n" + 
3925
			"            fileReader.read(in);\n" + 
3926
			"            while (true) {\n" + 
3927
			"                  fileReader.close();\n" + 
3928
			"                  FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + 
3929
			"                  loopReader.close();\n" + 
3930
			"                  break;\n" + 
3931
			"            }\n" + 
3932
			"        } else {\n" + 
3933
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3934
			"            if (f2)\n" + 
3935
			"                fileReader.close();\n" + 
3936
			"        }\n" + 
3937
			"    }\n" + 
3938
			"    public static void main(String[] args) throws IOException {\n" + 
3939
			"        new X().foo(true, true);\n" + 
3940
			"    }\n" + 
3941
			"}\n"
3942
		},
3943
		"----------\n" + 
3944
		"1. ERROR in X.java (at line 18)\n" + 
3945
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3946
		"	           ^^^^^^^^^^\n" + 
3947
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3948
		"----------\n",
3949
		null,
3950
		true,
3951
		options);
3952
}
3953
// Bug 349326 - [1.7] new warning for missing try-with-resources
3954
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
3955
public void test056j() {
3956
	Map options = getCompilerOptions();
3957
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3958
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3959
	this.runNegativeTest(
3960
		new String[] {
3961
			"X.java",
3962
			"import java.io.File;\n" +
3963
			"import java.io.FileReader;\n" +
3964
			"import java.io.IOException;\n" +
3965
			"public class X {\n" +
3966
			"    void foo() throws IOException {\n" +
3967
			"        File file = new File(\"somefile\");\n" +
3968
			"        FileReader fileReader = new FileReader(file);\n" +
3969
			"        read(fileReader);\n" +
3970
			"    }\n" +
3971
			"    void read(FileReader reader) { }\n" +
3972
			"    public static void main(String[] args) throws IOException {\n" +
3973
			"        new X().foo();\n" +
3974
			"    }\n" +
3975
			"}\n"
3976
		},
3977
		"----------\n" + 
3978
		"1. ERROR in X.java (at line 7)\n" + 
3979
		"	FileReader fileReader = new FileReader(file);\n" + 
3980
		"	           ^^^^^^^^^^\n" + 
3981
		"Potential resource leak: 'fileReader' may not be closed\n" + 
3982
		"----------\n",
3983
		null,
3984
		true,
3985
		options);
3986
}
3987
// Bug 349326 - [1.7] new warning for missing try-with-resources
3988
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
3989
public void test056jconditional() {
3990
	Map options = getCompilerOptions();
3991
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3992
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3993
	this.runNegativeTest(
3994
		new String[] {
3995
			"X.java",
3996
			"import java.io.File;\n" +
3997
			"import java.io.FileReader;\n" +
3998
			"import java.io.IOException;\n" +
3999
			"public class X {\n" +
4000
			"    void foo(boolean b) throws IOException {\n" +
4001
			"        File file = new File(\"somefile\");\n" +
4002
			"        FileReader fileReader = new FileReader(file);\n" +
4003
			"        synchronized (b ? this : new X()) {\n" +
4004
			"            new ReadDelegator(fileReader);\n" +
4005
			"        }\n" +
4006
			"    }\n" +
4007
			"    class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" +
4008
			"    public static void main(String[] args) throws IOException {\n" +
4009
			"        new X().foo(true);\n" +
4010
			"    }\n" +
4011
			"}\n"
4012
		},
4013
		"----------\n" + 
4014
		"1. ERROR in X.java (at line 7)\n" + 
4015
		"	FileReader fileReader = new FileReader(file);\n" + 
4016
		"	           ^^^^^^^^^^\n" + 
4017
		"Potential resource leak: 'fileReader' may not be closed\n" + 
4018
		"----------\n",
4019
		null,
4020
		true,
4021
		options);
4022
}
4023
// Bug 349326 - [1.7] new warning for missing try-with-resources
4024
// many locals, some are AutoCloseable.
4025
// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3,
4026
// doing so would create false positives.
4027
public void test056k() {
4028
	Map options = getCompilerOptions();
4029
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4030
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
4031
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4032
	this.runNegativeTest(
4033
		new String[] {
4034
			"X.java",
4035
			"import java.io.File;\n" +
4036
			"import java.io.FileReader;\n" +
4037
			"import java.io.IOException;\n" +
4038
			"public class X {\n" +
4039
			"    void foo() throws IOException {\n" +
4040
			"        int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" +
4041
			"            i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" +
4042
			"            i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" +
4043
			"            i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" +
4044
			"            i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" +
4045
			"        File file = new File(\"somefile\");\n" +
4046
			"        FileReader ra1 = null, ra2 = null;\n" +
4047
			"        try {\n" +
4048
			"            ra1 = new FileReader(file);\n" +
4049
			"            ra2 = new FileReader(file);\n" +
4050
			"            FileReader ra3 = new FileReader(file);\n" +
4051
			"            char[] in = new char[50];\n" +
4052
			"            ra1.read(in);\n" +
4053
			"            ra2.read(in);\n" +
4054
			"            ra3.close();\n" +
4055
			"        } finally {\n" +
4056
			"            ra1.close();\n" +
4057
			"        }\n" +
4058
			"        int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits
4059
			"        FileReader rb1 = null, rb2 = null;\n" +
4060
			"        try {\n" +
4061
			"            rb1 = new FileReader(file);\n" +
4062
			"            rb2 = new FileReader(file);\n" +
4063
			"            FileReader rb3 = new FileReader(file);\n" +
4064
			"            char[] in = new char[50];\n" +
4065
			"            rb1.read(in);\n" +
4066
			"            rb2.read(in);\n" +
4067
			"            rb3.close();\n" +
4068
			"        } finally {\n" +
4069
			"            rb1.close();\n" +
4070
			"        }\n" +
4071
			"    }\n" +
4072
			"    public static void main(String[] args) throws IOException {\n" +
4073
			"        new X().foo();\n" +
4074
			"    }\n" +
4075
			"}\n"
4076
		},
4077
		"----------\n" + 
4078
		"1. ERROR in X.java (at line 12)\n" + 
4079
		"	FileReader ra1 = null, ra2 = null;\n" + 
4080
		"	           ^^^\n" + 
4081
		"Resource \'ra1\' should be managed by try-with-resource\n" + 
4082
		"----------\n" + 
4083
		"2. ERROR in X.java (at line 15)\n" + 
4084
		"	ra2 = new FileReader(file);\n" + 
4085
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4086
		"Resource leak: 'ra2' is never closed\n" + 
4087
		"----------\n" + 
4088
		"3. ERROR in X.java (at line 16)\n" + 
4089
		"	FileReader ra3 = new FileReader(file);\n" + 
4090
		"	           ^^^\n" + 
4091
		"Resource \'ra3\' should be managed by try-with-resource\n" +
4092
		"----------\n" + 
4093
		"4. ERROR in X.java (at line 25)\n" + 
4094
		"	FileReader rb1 = null, rb2 = null;\n" + 
4095
		"	           ^^^\n" + 
4096
		"Resource \'rb1\' should be managed by try-with-resource\n" + 
4097
		"----------\n" + 
4098
		"5. ERROR in X.java (at line 28)\n" + 
4099
		"	rb2 = new FileReader(file);\n" + 
4100
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4101
		"Resource leak: 'rb2' is never closed\n" + 
4102
		"----------\n" + 
4103
		"6. ERROR in X.java (at line 29)\n" + 
4104
		"	FileReader rb3 = new FileReader(file);\n" + 
4105
		"	           ^^^\n" + 
4106
		"Resource \'rb3\' should be managed by try-with-resource\n" + 
4107
		"----------\n",
4108
		null,
4109
		true,
4110
		options);
4111
}
4112
// Bug 349326 - [1.7] new warning for missing try-with-resources
4113
// various non-problems
4114
public void test056l() {
4115
	Map options = getCompilerOptions();
4116
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4117
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4118
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4119
	this.runNegativeTest(
4120
		new String[] {
4121
			"X.java",
4122
			"import java.io.File;\n" +
4123
			"import java.io.FileReader;\n" +
4124
			"import java.io.IOException;\n" +
4125
			"public class X {\n" +
4126
			"    X(FileReader r0) {}\n" + // don't complain against argument
4127
			"    FileReader getReader() { return null; }\n" +
4128
			"    void foo(FileReader r1) throws IOException {\n" +
4129
			"        FileReader fileReader = getReader();\n" +
4130
			"        if (fileReader == null)\n" +
4131
			"            return;\n" + // don't complain, resource is actually null
4132
			"        FileReader r3 = getReader();\n" +
4133
			"        if (r3 == null)\n" +
4134
			"            r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null
4135
			"        try {\n" +
4136
			"            char[] in = new char[50];\n" +
4137
			"            fileReader.read(in);\n" +
4138
			"            r1.read(in);\n" +
4139
			"        } finally {\n" +
4140
			"            fileReader.close();\n" +
4141
			"            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
4142
			"        }\n" +
4143
			"    }\n" +
4144
			"    public static void main(String[] args) throws IOException {\n" +
4145
			"        FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" +
4146
			"        new X(r2).foo(new FileReader(new File(\"notthere\")));\n" +
4147
			"    }\n" +
4148
			"}\n"
4149
		},
4150
		"----------\n" + 
4151
		"1. ERROR in X.java (at line 8)\n" + 
4152
		"	FileReader fileReader = getReader();\n" + 
4153
		"	           ^^^^^^^^^^\n" + 
4154
		"Resource \'fileReader\' should be managed by try-with-resource\n" + 
4155
		"----------\n" + 
4156
		"2. ERROR in X.java (at line 11)\n" + 
4157
		"	FileReader r3 = getReader();\n" + 
4158
		"	           ^^\n" + 
4159
		"Resource 'r3' should be managed by try-with-resource\n" +
4160
		"----------\n" + 
4161
		"3. ERROR in X.java (at line 24)\n" + 
4162
		"	FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + 
4163
		"	           ^^\n" + 
4164
		"Potential resource leak: 'r2' may not be closed\n" + 
4165
		"----------\n",
4166
		null,
4167
		true,
4168
		options);
4169
}
4170
// Bug 349326 - [1.7] new warning for missing try-with-resources
4171
// nested try with early exit
4172
public void test056m() {
4173
	Map options = getCompilerOptions();
4174
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4175
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4176
	this.runConformTest(
4177
		new String[] {
4178
			"X.java",
4179
			"import java.io.File;\n" +
4180
			"import java.io.FileReader;\n" +
4181
			"import java.io.IOException;\n" +
4182
			"public class X {\n" +
4183
			"    void foo() {\n" +
4184
			"        File file = new File(\"somefile\");" +
4185
			"        try {\n" +
4186
			"            FileReader fileReader = new FileReader(file);\n" +
4187
			"            try {\n" +
4188
			"                char[] in = new char[50];\n" +
4189
			"                if (fileReader.read(in)==0)\n" +
4190
			"                    return;\n" +
4191
			"            } finally {\n" +
4192
			"		         fileReader.close();\n" +
4193
			"            }\n" +
4194
			"        } catch (IOException e) {\n" +
4195
			"            System.out.println(\"caught\");\n" +
4196
			"        }\n" +
4197
			"    }\n" +
4198
			"    public static void main(String[] args) {\n" +
4199
			"        new X().foo();\n" +
4200
			"    }\n" +
4201
			"}\n"
4202
		},
4203
		"caught", /*output*/
4204
		null/*classLibs*/,
4205
		true/*shouldFlush*/,
4206
		null/*vmargs*/,
4207
		options,
4208
		null/*requestor*/);
4209
}
4210
// Bug 349326 - [1.7] new warning for missing try-with-resources
4211
// nested try should not interfere with earlier analysis.
4212
public void test056n() {
4213
	Map options = getCompilerOptions();
4214
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4215
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4216
	this.runConformTest(
4217
		new String[] {
4218
			"X.java",
4219
			"import java.io.File;\n" +
4220
			"import java.io.FileReader;\n" +
4221
			"import java.io.IOException;\n" +
4222
			"import java.io.FileNotFoundException;\n" +
4223
			"public class X {\n" +
4224
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4225
			"		FileReader fr1 = new FileReader(someFile);\n" + 
4226
			"		try {\n" + 
4227
			"			fr1.read(buf);\n" + 
4228
			"		} finally {\n" + 
4229
			"			fr1.close();\n" + 
4230
			"		}\n" + 
4231
			"		try {\n" + 
4232
			"			FileReader fr3 = new FileReader(someFile);\n" + 
4233
			"			try {\n" + 
4234
			"			} finally {\n" + 
4235
			"				fr3.close();\n" + 
4236
			"			}\n" + 
4237
			"		} catch (IOException e) {\n" + 
4238
			"		}\n" + 
4239
			"	 }\n" +
4240
			"    public static void main(String[] args) throws IOException {\n" +
4241
			"        try {\n" +
4242
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4243
			"        } catch (FileNotFoundException e) {\n" +
4244
			"            System.out.println(\"caught\");\n" +
4245
			"        }\n" +
4246
			"    }\n" +
4247
			"}\n"
4248
		},
4249
		"caught", /*output*/
4250
		null/*classLibs*/,
4251
		true/*shouldFlush*/,
4252
		null/*vmargs*/,
4253
		options,
4254
		null/*requestor*/);
4255
}
4256
// Bug 349326 - [1.7] new warning for missing try-with-resources
4257
// if close is guarded by null check this should still be recognized as definitely closed
4258
public void test056o() {
4259
	Map options = getCompilerOptions();
4260
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4261
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4262
	this.runConformTest(
4263
		new String[] {
4264
			"X.java",
4265
			"import java.io.File;\n" +
4266
			"import java.io.FileReader;\n" +
4267
			"import java.io.IOException;\n" +
4268
			"import java.io.FileNotFoundException;\n" +
4269
			"public class X {\n" +
4270
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4271
			"		FileReader fr1 = null;\n" + 
4272
			"		try {\n" +
4273
			"           fr1 = new FileReader(someFile);" + 
4274
			"			fr1.read(buf);\n" + 
4275
			"		} finally {\n" + 
4276
			"			if (fr1 != null)\n" +
4277
			"               try {\n" +
4278
			"                   fr1.close();\n" +
4279
			"               } catch (IOException e) { /*do nothing*/ }\n" + 
4280
			"		}\n" + 
4281
			"	 }\n" +
4282
			"    public static void main(String[] args) throws IOException {\n" +
4283
			"        try {\n" +
4284
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4285
			"        } catch (FileNotFoundException e) {\n" +
4286
			"            System.out.println(\"caught\");\n" +
4287
			"        }\n" +
4288
			"    }\n" +
4289
			"}\n"
4290
		},
4291
		"caught", /*output*/
4292
		null/*classLibs*/,
4293
		true/*shouldFlush*/,
4294
		null/*vmargs*/,
4295
		options,
4296
		null/*requestor*/);
4297
}
4298
// Bug 349326 - [1.7] new warning for missing try-with-resources
4299
// a method uses an AutoCloseable without ever closing it, type from a type variable
4300
public void test056p() {
4301
	Map options = getCompilerOptions();
4302
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4303
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
4304
	this.runNegativeTest(
4305
		new String[] {
4306
			"X.java",
4307
			"import java.io.File;\n" +
4308
			"import java.io.FileReader;\n" +
4309
			"import java.io.Reader;\n" +
4310
			"import java.io.IOException;\n" +
4311
			"public abstract class X <T extends Reader> {\n" +
4312
			"    void foo() throws IOException {\n" +
4313
			"        File file = new File(\"somefile\");\n" +
4314
			"        T fileReader = newReader(file);\n" +
4315
			"        char[] in = new char[50];\n" +
4316
			"        fileReader.read(in);\n" +
4317
			"    }\n" +
4318
			"    abstract T newReader(File file) throws IOException;\n" +
4319
			"    public static void main(String[] args) throws IOException {\n" +
4320
			"        new X<FileReader>() {\n" +
4321
			"            FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" +
4322
			"        }.foo();\n" +
4323
			"    }\n" +
4324
			"}\n"
4325
		},
4326
		"----------\n" + 
4327
		"1. ERROR in X.java (at line 8)\n" + 
4328
		"	T fileReader = newReader(file);\n" + 
4329
		"	  ^^^^^^^^^^\n" + 
4330
		"Resource leak: 'fileReader' is never closed\n" +
4331
		"----------\n",
4332
		null,
4333
		true,
4334
		options);
4335
}
4336
// Bug 349326 - [1.7] new warning for missing try-with-resources
4337
// closed in dead code
4338
public void test056q() {
4339
	Map options = getCompilerOptions();
4340
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4341
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4342
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4343
	this.runNegativeTest(
4344
		new String[] {
4345
			"X.java",
4346
			"import java.io.File;\n" +
4347
			"import java.io.FileReader;\n" +
4348
			"import java.io.IOException;\n" +
4349
			"public class X {\n" +
4350
			"    void foo() throws IOException {\n" +
4351
			"        File file = new File(\"somefile\");\n" +
4352
			"        FileReader fileReader = new FileReader(file);\n" +
4353
			"        char[] in = new char[50];\n" +
4354
			"        fileReader.read(in);\n" +
4355
			"        if (2*2 == 4)\n" +
4356
			"        	return;\n" +
4357
			"        fileReader.close();\n" +
4358
			"    }\n" +
4359
			"    public static void main(String[] args) throws IOException {\n" +
4360
			"        new X().foo();\n" +
4361
			"    }\n" +
4362
			"}\n"
4363
		},
4364
		"----------\n" + 
4365
		"1. ERROR in X.java (at line 7)\n" + 
4366
		"	FileReader fileReader = new FileReader(file);\n" + 
4367
		"	           ^^^^^^^^^^\n" + 
4368
		"Resource leak: \'fileReader\' is never closed\n" + 
4369
		"----------\n" + 
4370
		"2. WARNING in X.java (at line 10)\n" + 
4371
		"	if (2*2 == 4)\n" + 
4372
		"	    ^^^^^^^^\n" + 
4373
		"Comparing identical expressions\n" + 
4374
		"----------\n" + 
4375
		"3. WARNING in X.java (at line 12)\n" + 
4376
		"	fileReader.close();\n" + 
4377
		"	^^^^^^^^^^^^^^^^^^\n" + 
4378
		"Dead code\n" + 
4379
		"----------\n",
4380
		null,
4381
		true,
4382
		options);
4383
}
4384
// Bug 349326 - [1.7] new warning for missing try-with-resources
4385
// closed in dead code
4386
public void test056r() {
4387
	Map options = getCompilerOptions();
4388
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4389
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4390
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4391
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4392
	this.runNegativeTest(
4393
		new String[] {
4394
			"X.java",
4395
			"import java.io.File;\n" +
4396
			"import java.io.FileReader;\n" +
4397
			"import java.io.IOException;\n" +
4398
			"public class X {\n" +
4399
			"    void foo() throws IOException {\n" +
4400
			"        File file = new File(\"somefile\");\n" +
4401
			"        FileReader fr = new FileReader(file);\n" +
4402
			"  		 Object b = null;\n" + 
4403
			"        fr.close();\n" + 
4404
			"        if (b != null) {\n" + 
4405
			"            fr = new FileReader(file);\n" + 
4406
			"            return;\n" + 
4407
			"        } else {\n" + 
4408
			"            System.out.print(42);\n" + 
4409
			"        }\n" + 
4410
			"        return;     // Should not complain about fr\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 10)\n" + 
4419
		"	if (b != null) {\n" + 
4420
		"            fr = new FileReader(file);\n" + 
4421
		"            return;\n" + 
4422
		"        } else {\n" + 
4423
		"	               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4424
		"Dead code\n" + 
4425
		"----------\n" + 
4426
		"2. WARNING in X.java (at line 13)\n" + 
4427
		"	} else {\n" + 
4428
		"            System.out.print(42);\n" + 
4429
		"        }\n" + 
4430
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4431
		"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + 
4432
		"----------\n",
4433
		null,
4434
		true,
4435
		options);
4436
}
4437
// Bug 349326 - [1.7] new warning for missing try-with-resources
4438
// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation
4439
public void test056s() {
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
	this.runNegativeTest(
4445
		new String[] {
4446
			"X.java",
4447
			"import java.io.File;\n" + 
4448
			"import java.io.FileReader;\n" + 
4449
			"import java.io.IOException;\n" + 
4450
			"public class X {\n" + 
4451
			"    void foo() throws IOException {\n" + 
4452
			"        File file = new File(\"somefile\");\n" + 
4453
			"        try (FileReader fileReader = new FileReader(file);) {\n" + 
4454
			"            char[] in = new char[50];\n" + 
4455
			"            fileReader.read(in);\n" + 
4456
			"            fileReader = new FileReader(file);  // debug here\n" + 
4457
			"            fileReader.read(in);\n" + 
4458
			"        }\n" + 
4459
			"    }\n" +
4460
			"    public static void main(String[] args) throws IOException {\n" + 
4461
			"        new X().foo();\n" + 
4462
			"    }\n" + 
4463
			"}\n"
4464
		},
4465
		"----------\n" + 
4466
		"1. ERROR in X.java (at line 10)\n" + 
4467
		"	fileReader = new FileReader(file);  // debug here\n" + 
4468
		"	^^^^^^^^^^\n" + 
4469
		"The resource fileReader of a try-with-resources statement cannot be assigned\n" + 
4470
		"----------\n",
4471
		null,
4472
		true,
4473
		options);
4474
}
4475
// Bug 349326 - [1.7] new warning for missing try-with-resources
4476
// resource is closed, dead code follows
4477
public void test056t() {
4478
	Map options = getCompilerOptions();
4479
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4480
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4481
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4482
	this.runNegativeTest(
4483
		new String[] {
4484
			"X.java",
4485
			"import java.io.FileReader;\n" + 
4486
			"import java.io.IOException;\n" + 
4487
			"public class X {\n" + 
4488
			"    void foo31() throws IOException {\n" + 
4489
			"        FileReader reader = new FileReader(\"file\"); //warning\n" +
4490
			"        if (reader != null) {\n" + 
4491
			"            reader.close();\n" + 
4492
			"        } else {\n" + 
4493
			"            // nop\n" + 
4494
			"        }\n" + 
4495
			"    }\n" + 
4496
			"    public static void main(String[] args) throws IOException {\n" + 
4497
			"        new X().foo31();\n" + 
4498
			"    }\n" + 
4499
			"}\n"
4500
		},
4501
		"----------\n" + 
4502
		"1. ERROR in X.java (at line 8)\n" + 
4503
		"	} else {\n" + 
4504
		"            // nop\n" + 
4505
		"        }\n" + 
4506
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4507
		"Dead code\n" + 
4508
		"----------\n",
4509
		null,
4510
		true,
4511
		options);
4512
}
4513
// Bug 349326 - [1.7] new warning for missing try-with-resources
4514
// resource is reassigned within t-w-r with different resource
4515
// disabled due to Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
4516
public void _test056u() {
4517
	Map options = getCompilerOptions();
4518
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4519
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4520
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4521
	this.runNegativeTest(
4522
		new String[] {
4523
			"X.java",
4524
			"import java.io.FileReader;\n" + 
4525
			"public class X {\n" + 
4526
			"    void foo() throws Exception {\n" + 
4527
			"        FileReader reader1 = new FileReader(\"file1\");\n" + 
4528
			"        FileReader reader2 = new FileReader(\"file2\");\n" + 
4529
			"        reader2 = reader1;// warning 1\n" + 
4530
			"        try (FileReader reader3 = new FileReader(\"file3\")) {\n" + 
4531
			"            int ch;\n" + 
4532
			"            while ((ch = reader2.read()) != -1) {\n" + 
4533
			"                System.out.println(ch);\n" + 
4534
			"                reader1.read();\n" + 
4535
			"            }\n" + 
4536
			"            reader2 = reader1;// warning 2\n" + 
4537
			"            reader2 = reader1;// warning 3\n" + 
4538
			"        } finally {\n" + 
4539
			"            if (reader2 != null) {\n" + 
4540
			"                reader2.close();\n" + 
4541
			"            } else {\n" + 
4542
			"                System.out.println();\n" + 
4543
			"            }\n" + 
4544
			"        }\n" + 
4545
			"    }\n" + 
4546
			"}\n"
4547
		},
4548
		"----------\n" + 
4549
		"1. ERROR in X.java (at line 4)\n" + 
4550
		"	FileReader reader1 = new FileReader(\"file1\");\n" + 
4551
		"	           ^^^^^^^\n" + 
4552
		"Resource leak: \'reader1\' is never closed\n" + 
4553
		"----------\n" + 
4554
		"2. ERROR in X.java (at line 4)\n" + 
4555
		"	reader2 = reader1;// warning 1\n" + 
4556
		"	^^^^^^^^^^^^^^^^^\n" + 
4557
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4558
		"----------\n" + 
4559
		"3. ERROR in X.java (at line 13)\n" + 
4560
		"	reader2 = reader1;// warning 2\n" + 
4561
		"	^^^^^^^^^^^^^^^^^\n" + 
4562
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4563
		"----------\n" + 
4564
		"4. ERROR in X.java (at line 14)\n" + 
4565
		"	reader2 = reader1;// warning 3\n" + 
4566
		"	^^^^^^^^^^^^^^^^^\n" + 
4567
		"Resource leak: \'reader2\' is not closed at this location\n" + 
4568
		"----------\n",
4569
		null,
4570
		true,
4571
		options);
4572
}
3383
public static Class testClass() {
4573
public static Class testClass() {
3384
	return TryWithResourcesStatementTest.class;
4574
	return TryWithResourcesStatementTest.class;
3385
}
4575
}

Return to bug 349326