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)) < 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);
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);
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)) < 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) {
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);
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 (+165 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.TypeBinding;
28
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
29
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
30
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
31
32
/**
33
 * A faked local variable declaration used for keeping track of data flows of a
34
 * special variable. Certain events will be recorded by changing the null info
35
 * for this variable.
36
 * 
37
 * See bug 349326 - [1.7] new warning for missing try-with-resources
38
 */
39
public class FakedTrackingVariable extends LocalDeclaration {
40
41
	/** 
42
	 * If close() is invoked from a nested method (inside a local type) 
43
	 * report remaining problems only as potential.
44
	 */
45
	public boolean closedInNestedMethod; 
46
47
	MethodScope methodScope; // designates the method declaring this variable
48
	
49
	public LocalVariableBinding originalBinding; // the real local being tracked
50
	
51
	HashMap recordedLocations; // initially null, ASTNode -> Integer 
52
53
	public FakedTrackingVariable(LocalVariableBinding original, Statement location) {
54
		super(original.name, location.sourceStart, location.sourceEnd);
55
		this.type = new SingleTypeReference(
56
				TypeConstants.OBJECT,
57
				((long)this.sourceStart <<32)+this.sourceEnd);
58
		this.methodScope = original.declaringScope.methodScope();
59
		this.originalBinding = original;
60
		resolve(original.declaringScope);
61
	}
62
	
63
	public void generateCode(BlockScope currentScope, CodeStream codeStream)
64
	{ /* NOP - this variable is completely dummy, ie. for analysis only. */ }
65
66
	public void resolve (BlockScope scope) {
67
		// only need the binding, which is used as reference in FlowInfo methods.
68
		this.binding = new LocalVariableBinding(
69
				this.name,
70
				scope.getJavaLangObject(),  // dummy, just needs to be a reference type
71
				0,
72
				false);
73
		this.binding.setConstant(Constant.NotAConstant);
74
		this.binding.useFlag = LocalVariableBinding.USED;
75
		// use a free slot without assigning it:
76
		this.binding.id = scope.registerTrackingVariable(this);
77
	}
78
79
	/**
80
	 * If expression resolves to a local variable binding of type AutoCloseable,
81
	 * answer the variable that tracks closing of that local, creating it if needed.
82
	 * @param expression
83
	 * @return a new {@link FakedTrackingVariable} or null.
84
	 */
85
	public static FakedTrackingVariable getCloseTrackingVariable(Expression expression) {
86
		if (expression instanceof SingleNameReference) {
87
			SingleNameReference name = (SingleNameReference) expression;
88
			if (name.binding instanceof LocalVariableBinding) {
89
				LocalVariableBinding local = (LocalVariableBinding)name.binding;
90
				if (local.closeTracker != null)
91
					return local.closeTracker;
92
				if (local.isParameter() || !isAutoCloseable(expression.resolvedType))
93
					return null;
94
				// tracking var doesn't yet exist. This happens in finally block
95
				// which is analyzed before the corresponding try block
96
				Statement location = local.declaration;
97
				return local.closeTracker = new FakedTrackingVariable(local, location);
98
			}
99
		}
100
		return null;
101
	}
102
103
	/** if 'invocationSite' is a call to close() that has a registered tracking variable, answer that variable's binding. */
104
	public static LocalVariableBinding getTrackerForCloseCall(ASTNode invocationSite) {
105
		if (invocationSite instanceof MessageSend) {
106
			MessageSend send = (MessageSend) invocationSite;
107
			if (CharOperation.equals(TypeConstants.CLOSE, send.selector) && send.receiver instanceof SingleNameReference) {
108
				Binding receiverBinding = ((SingleNameReference)send.receiver).binding;
109
				if (receiverBinding instanceof LocalVariableBinding) {
110
					FakedTrackingVariable trackingVariable = ((LocalVariableBinding)receiverBinding).closeTracker;
111
					if (trackingVariable != null)
112
						return trackingVariable.binding;
113
				}
114
			}
115
		}
116
		return null;
117
	}
118
119
	public static FlowInfo markPotentialClosing(Expression expression, FlowInfo flowInfo) {
120
		FakedTrackingVariable trackVar = getCloseTrackingVariable(expression);
121
		if (trackVar != null) {
122
			// insert info that the tracked resource *may* be closed (by the target method, i.e.)
123
			FlowInfo infoResourceIsClosed = flowInfo.copy();
124
			infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding);
125
			return FlowInfo.conditional(flowInfo, infoResourceIsClosed);
126
		}
127
		return flowInfo;
128
	}
129
130
	/** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */
131
	public static boolean isAutoCloseable(TypeBinding typeBinding) {
132
		return typeBinding instanceof ReferenceBinding
133
			&& ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable);
134
	}
135
	
136
	public void recordErrorLocation(ASTNode location, int nullStatus) {
137
		if (this.recordedLocations == null)
138
			this.recordedLocations = new HashMap();
139
		this.recordedLocations.put(location, new Integer(nullStatus));
140
	}
141
142
	public boolean reportRecordedErrors(ProblemReporter problemReporter) {
143
		boolean hasReported = false;
144
		if (this.recordedLocations != null) {
145
			Iterator locations = this.recordedLocations.entrySet().iterator();
146
			while (locations.hasNext()) {
147
				Map.Entry entry = (Entry) locations.next();
148
				reportError(problemReporter, (ASTNode)entry.getKey(), ((Integer)entry.getValue()).intValue());
149
				hasReported = true;
150
			}
151
		}
152
		return hasReported;
153
	}
154
	
155
	public void reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) {
156
		if (nullStatus == FlowInfo.NULL) {
157
			if (this.closedInNestedMethod)
158
				problemReporter.potentiallyUnclosedCloseable(this, location);
159
			else
160
				problemReporter.unclosedCloseable(this, location);
161
		} else if (nullStatus == FlowInfo.POTENTIALLY_NULL) {
162
			problemReporter.potentiallyUnclosedCloseable(this, location);
163
		}		
164
	}
165
}
(-)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) < 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) < 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);
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);
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)) < 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 / +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 - 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) {
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
				scope.checkUnclosedCloseables(flowInfo, flowContext, null);
80
			}
83
			}
81
			return COMPLAINED_UNREACHABLE;
84
			return COMPLAINED_UNREACHABLE;
82
		} else {
85
		} else {
83
			if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) {
86
			if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) {
84
				scope.problemReporter().fakeReachable(this);
87
				scope.problemReporter().fakeReachable(this);
88
				scope.checkUnclosedCloseables(flowInfo, flowContext, null);
85
			}
89
			}
86
			return COMPLAINED_FAKE_REACHABLE;
90
			return COMPLAINED_FAKE_REACHABLE;
87
		}
91
		}
(-)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)) < 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) < 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/ExceptionHandlingFlowContext.java (-8 / +26 lines)
Lines 7-28 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.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
13
import java.util.ArrayList;
14
import java.util.ArrayList;
14
15
15
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
16
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
16
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
17
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
17
import org.eclipse.jdt.internal.compiler.ast.Argument;
18
import org.eclipse.jdt.internal.compiler.ast.Argument;
18
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
19
import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
19
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
20
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
20
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
21
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
21
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
22
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
23
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
22
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
24
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
23
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
25
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
24
import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
25
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
27
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
28
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
29
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
27
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
30
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
28
import org.eclipse.jdt.internal.compiler.lookup.Scope;
31
import org.eclipse.jdt.internal.compiler.lookup.Scope;
Lines 180-186 Link Here
180
	return node;
183
	return node;
181
}
184
}
182
185
183
186
public int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo) {
187
	// collect info from normal flow and exceptional flows:
188
	int status = flowInfo.nullStatus(local);
189
	if (this.initsOnExceptions != null)
190
		for (int i = 0; i < this.initsOnExceptions.length; i++)
191
			status |= (this.initsOnExceptions[i].nullStatus(local) & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL));
192
	return status;
193
}
184
194
185
public String individualToString() {
195
public String individualToString() {
186
	StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
196
	StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
Lines 251-257 Link Here
251
		TypeBinding raisedException,
261
		TypeBinding raisedException,
252
		TypeBinding caughtException,
262
		TypeBinding caughtException,
253
		ASTNode invocationSite,
263
		ASTNode invocationSite,
254
		boolean wasAlreadyDefinitelyCaught) {
264
		boolean wasAlreadyDefinitelyCaught,
265
		boolean isFirstException) {
255
266
256
	int index = this.indexes.get(exceptionType);
267
	int index = this.indexes.get(exceptionType);
257
	int cacheIndex = index / ExceptionHandlingFlowContext.BitCacheSize;
268
	int cacheIndex = index / ExceptionHandlingFlowContext.BitCacheSize;
Lines 265-274 Link Here
265
		CatchParameterBinding catchParameter = (CatchParameterBinding) this.catchArguments[catchBlock].binding;
276
		CatchParameterBinding catchParameter = (CatchParameterBinding) this.catchArguments[catchBlock].binding;
266
		catchParameter.setPreciseType(caughtException);
277
		catchParameter.setPreciseType(caughtException);
267
	}
278
	}
268
	this.initsOnExceptions[catchBlock] =
279
	UnconditionalFlowInfo mergedInfo =
269
		(this.initsOnExceptions[catchBlock].tagBits & FlowInfo.UNREACHABLE) == 0 ?
280
			(this.initsOnExceptions[catchBlock].tagBits & FlowInfo.UNREACHABLE) == 0 ?
270
			this.initsOnExceptions[catchBlock].mergedWith(flowInfo):
281
					this.initsOnExceptions[catchBlock].mergedWith(flowInfo):
271
			flowInfo.unconditionalCopy();
282
						flowInfo.unconditionalCopy();
283
	if (isFirstException) {
284
		LocalVariableBinding trackBinding = FakedTrackingVariable.getTrackerForCloseCall(invocationSite);
285
		if (trackBinding != null)
286
			// if the first statement throwing an exception is a close() call, consider the corresponding resource as closed despite the exception
287
			mergedInfo.markAsDefinitelyNonNull(trackBinding);
288
	}
289
	this.initsOnExceptions[catchBlock] = mergedInfo;
272
}
290
}
273
291
274
public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
292
public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.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.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
Lines 17-22 Link Here
17
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
18
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
18
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
19
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
19
import org.eclipse.jdt.internal.compiler.lookup.Scope;
20
import org.eclipse.jdt.internal.compiler.lookup.Scope;
21
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
20
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
22
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
21
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
23
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
22
24
Lines 34-44 Link Here
34
	Expression[] nullReferences;
36
	Expression[] nullReferences;
35
	int[] nullCheckTypes;
37
	int[] nullCheckTypes;
36
	int nullCount;
38
	int nullCount;
39
	boolean hasSeenExceptions;
37
40
38
	public FinallyFlowContext(FlowContext parent, ASTNode associatedNode) {
41
	public FinallyFlowContext(FlowContext parent, ASTNode associatedNode) {
39
		super(parent, associatedNode);
42
		super(parent, associatedNode);
40
	}
43
	}
41
44
45
	public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
46
		checkExceptionHandlers(raisedExceptions, location, flowInfo, scope, !this.hasSeenExceptions);
47
		this.hasSeenExceptions = true;
48
	}
49
42
/**
50
/**
43
 * Given some contextual initialization info (derived from a try block or a catch block), this
51
 * Given some contextual initialization info (derived from a try block or a catch block), this
44
 * code will check that the subroutine context does not also initialize a final variable potentially set
52
 * code will check that the subroutine context does not also initialize a final variable potentially set
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java (-6 / +63 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.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
13
import java.util.ArrayList;
14
import java.util.ArrayList;
15
14
import org.eclipse.jdt.core.compiler.CharOperation;
16
import org.eclipse.jdt.core.compiler.CharOperation;
15
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
16
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
17
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
18
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
17
import org.eclipse.jdt.internal.compiler.ast.Expression;
19
import org.eclipse.jdt.internal.compiler.ast.Expression;
18
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
20
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
19
import org.eclipse.jdt.internal.compiler.ast.Reference;
21
import org.eclipse.jdt.internal.compiler.ast.Reference;
Lines 153-159 Link Here
153
								raisedException,
155
								raisedException,
154
								raisedException, // precise exception that will be caught
156
								raisedException, // precise exception that will be caught
155
								location,
157
								location,
156
								definitelyCaught);
158
								definitelyCaught,
159
								false/* not first exception in finally block*/);
157
							// was it already definitely caught ?
160
							// was it already definitely caught ?
158
							definitelyCaught = true;
161
							definitelyCaught = true;
159
							break;
162
							break;
Lines 164-170 Link Here
164
								raisedException,
167
								raisedException,
165
								caughtException,
168
								caughtException,
166
								location,
169
								location,
167
								false);
170
								false,
171
								false/* not first exception in finally block*/);
168
							// was not caught already per construction
172
							// was not caught already per construction
169
					}
173
					}
170
				}
174
				}
Lines 213-220 Link Here
213
		scope.problemReporter().unhandledException(raisedException, location);
217
		scope.problemReporter().unhandledException(raisedException, location);
214
	}
218
	}
215
}
219
}
216
217
public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
220
public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
221
	checkExceptionHandlers(raisedExceptions, location, flowInfo, scope, false/*not known to be first in finally*/);
222
}
223
224
public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope, boolean isFirstExceptionInFinally) {
218
	// check that all the argument exception types are handled
225
	// check that all the argument exception types are handled
219
	// JDK Compatible implementation - when an exception type is thrown,
226
	// JDK Compatible implementation - when an exception type is thrown,
220
	// all related catch blocks are marked as reachable... instead of those only
227
	// all related catch blocks are marked as reachable... instead of those only
Lines 276-282 Link Here
276
										raisedException,
283
										raisedException,
277
										raisedException, // precise exception that will be caught
284
										raisedException, // precise exception that will be caught
278
										location,
285
										location,
279
										locallyCaught[raisedIndex]);
286
										locallyCaught[raisedIndex],
287
										isFirstExceptionInFinally);
280
									// was already definitely caught ?
288
									// was already definitely caught ?
281
									if (!locallyCaught[raisedIndex]) {
289
									if (!locallyCaught[raisedIndex]) {
282
										locallyCaught[raisedIndex] = true;
290
										locallyCaught[raisedIndex] = true;
Lines 291-297 Link Here
291
										raisedException,
299
										raisedException,
292
										caughtException, 
300
										caughtException, 
293
										location,
301
										location,
294
										false);
302
										false,
303
										isFirstExceptionInFinally);
295
									// was not caught already per construction
304
									// was not caught already per construction
296
							}
305
							}
297
						}
306
						}
Lines 391-396 Link Here
391
	return null;
400
	return null;
392
}
401
}
393
402
403
/**
404
 * Answer the combined null status that local will have after this flow context.
405
 * Subclasses will respect break and exception exits.
406
 */
407
public int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo) {
408
	return flowInfo.nullStatus(local);
409
}
410
394
/*
411
/*
395
 * lookup through break labels
412
 * lookup through break labels
396
 */
413
 */
Lines 732-735 Link Here
732
	buffer.append(individualToString()).append('\n');
749
	buffer.append(individualToString()).append('\n');
733
	return buffer.toString();
750
	return buffer.toString();
734
}
751
}
752
753
/**
754
 * Get the null status that local will have after the current point as indicated by flowInfo and flowContext
755
 * @param local
756
 * @param flowInfo
757
 * @param flowContext may be null
758
 * @return a bitset from the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}.
759
 */
760
public static int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo, FlowContext flowContext) {
761
	int reachMode = flowInfo.reachMode();
762
	int status = 0;
763
	try {
764
		// unreachable flowInfo is too shy in reporting null-issues, temporarily forget reachability:
765
		if (reachMode != FlowInfo.REACHABLE)
766
			flowInfo.tagBits &= ~FlowInfo.UNREACHABLE;
767
		status = (flowContext != null) 
768
						? flowContext.getNullStatusAfter(local, flowInfo)
769
						: flowInfo.nullStatus(local);
770
	} finally {
771
		// reset
772
		flowInfo.tagBits |= reachMode;
773
	}
774
	// at this point some combinations are not useful so flatten to a single bit:
775
	return mergeNullStatus(status);
776
}
777
778
/* Merge the bits NULL, NON_NULL, POTENTIALLY_NULL, POTENTIALLY_NON_NULL to a one-bit answer. */
779
private static int mergeNullStatus(int status) {
780
	if ((status & FlowInfo.NULL) != 0) {
781
		if ((status & (FlowInfo.NON_NULL | FlowInfo.POTENTIALLY_NON_NULL)) != 0)
782
			return FlowInfo.POTENTIALLY_NULL; 	// null + doubt = pot null
783
		return FlowInfo.NULL;
784
	} else if ((status & FlowInfo.NON_NULL) != 0) {
785
		if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
786
			return FlowInfo.POTENTIALLY_NULL;	// non-null + doubt = pot null
787
		return FlowInfo.NON_NULL;
788
	} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
789
		return FlowInfo.POTENTIALLY_NULL;
790
	return status;
791
}
735
}
792
}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.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.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
Lines 67-73 Link Here
67
		TypeBinding raisedException,
68
		TypeBinding raisedException,
68
		TypeBinding caughtException,
69
		TypeBinding caughtException,
69
		ASTNode invocationSite,
70
		ASTNode invocationSite,
70
		boolean wasMasked) {
71
		boolean wasMasked,
72
		boolean isFirstExceptionInFinally) {
71
73
72
		// even if unreachable code, need to perform unhandled exception diagnosis
74
		// even if unreachable code, need to perform unhandled exception diagnosis
73
		int size = this.thrownExceptions.length;
75
		int size = this.thrownExceptions.length;
(-)compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java (-2 / +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 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
10
 *     Stephan Herrmann - contributions for
11
 *     							Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
12
 *     							Bug 349326 - [1.7] new warning for missing try-with-resources
11
 *******************************************************************************/
13
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.flow;
14
package org.eclipse.jdt.internal.compiler.flow;
13
15
Lines 59-65 Link Here
59
		void simulateThrowAfterLoopBack(FlowInfo flowInfo) {
61
		void simulateThrowAfterLoopBack(FlowInfo flowInfo) {
60
			this.catchingContext.recordHandlingException(this.caughtException,
62
			this.catchingContext.recordHandlingException(this.caughtException,
61
					flowInfo.unconditionalInits(), null, // raised exception, irrelevant here,
63
					flowInfo.unconditionalInits(), null, // raised exception, irrelevant here,
62
					null, null, /* invocation site, irrelevant here */ true // we have no business altering the needed status.
64
					null,
65
					null, // invocation site, irrelevant here
66
					true, // we have no business altering the needed status.
67
					false // not known to be the first exception in a finally block
63
					);
68
					);
64
		}
69
		}
65
	}
70
	}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java (+10 lines)
Lines 7-17 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.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
12
13
13
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
14
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
14
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
15
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
16
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
15
17
16
/**
18
/**
17
 * Reflects the context of code analysis, keeping track of enclosing
19
 * Reflects the context of code analysis, keeping track of enclosing
Lines 31-36 Link Here
31
	return this.breakLabel;
33
	return this.breakLabel;
32
}
34
}
33
35
36
public int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo) {
37
	// collect info from normal flow and breaks flows:
38
	int status = flowInfo.nullStatus(local);
39
	if (this.initsOnBreak != null)
40
		status |= this.initsOnBreak.nullStatus(local);
41
	return status;
42
}
43
34
public String individualToString() {
44
public String individualToString() {
35
	StringBuffer buffer = new StringBuffer("Switch flow context"); //$NON-NLS-1$
45
	StringBuffer buffer = new StringBuffer("Switch flow context"); //$NON-NLS-1$
36
	buffer.append("[initsOnBreak -").append(this.initsOnBreak.toString()).append(']'); //$NON-NLS-1$
46
	buffer.append("[initsOnBreak -").append(this.initsOnBreak.toString()).append(']'); //$NON-NLS-1$
(-)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 (+110 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 = FlowContext.getNullStatusAfter(trackingVar.binding, flowInfo, flowContext);
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(problemReporter())) // ... 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
}
960
}
1070
}
(-)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 / +11 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 438-445 Link Here
438
				case 'A' :
443
				case 'A' :
439
					switch(typeName.length) {
444
					switch(typeName.length) {
440
						case 13 :
445
						case 13 :
441
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2]))
446
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
442
								this.id = TypeIds.T_JavaLangAutoCloseable;
447
								this.id = TypeIds.T_JavaLangAutoCloseable;
448
								this.typeBits |= TypeIds.BitAutoCloseable; 
449
							}
443
							return;
450
							return;
444
						case 14:
451
						case 14:
445
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
452
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
Lines 937-942 Link Here
937
public final boolean hasRestrictedAccess() {
944
public final boolean hasRestrictedAccess() {
938
	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
945
	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
939
}
946
}
947
/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */
948
abstract public boolean hasTypeBit(int bit);
940
949
941
/** Answer true if the receiver implements anInterface or is identical to anInterface.
950
/** Answer true if the receiver implements anInterface or is identical to anInterface.
942
* If searchHierarchy is true, then also search the receiver's superclasses.
951
* 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 (+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.lookup;
12
package org.eclipse.jdt.internal.compiler.lookup;
12
13
Lines 151-156 Link Here
151
			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
152
			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
152
	};
153
	};
153
	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
154
	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
155
	char[] CLOSE = "close".toCharArray(); //$NON-NLS-1$
154
156
155
	// Constraints for generic type argument inference
157
	// Constraints for generic type argument inference
156
	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
158
	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.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 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;
185
}
192
}
(-)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 = Potentially leaking resource '{0}': is not closed on all paths
650
886 = Potentially leaking resource '{0}': may not be closed at this location
651
887 = Leaking resource '{0}': is never closed
652
888 = Leaking resource '{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/TryWithResourcesStatementTest.java (-5 / +1049 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[] { "test056i2" };
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
		"Leaking resource '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
		"Leaking resource '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
		"Leaking resource '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 exception may occur earlier.
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
	this.runNegativeTest(
3437
		new String[] {
3438
			"X.java",
3439
			"import java.io.File;\n" +
3440
			"import java.io.FileReader;\n" +
3441
			"import java.io.IOException;\n" +
3442
			"public class X {\n" +
3443
			"    void foo() throws IOException {\n" +
3444
			"        File file = new File(\"somefile\");\n" +
3445
			"        FileReader fileReader = new FileReader(file);\n" +
3446
			"        char[] in = new char[50];\n" +
3447
			"        fileReader.read(in);\n" +
3448
			"		 fileReader.close();\n" +
3449
			"    }\n" +
3450
			"    public static void main(String[] args) {\n" +
3451
			"        try {\n" +
3452
			"            new X().foo();\n" +
3453
			"        } catch (IOException ioex) {\n" +
3454
			"            System.out.println(\"caught\");\n" +
3455
			"        }\n" +
3456
			"    }\n" +
3457
			"}\n"
3458
		},
3459
		"----------\n" + 
3460
		"1. ERROR in X.java (at line 7)\n" + 
3461
		"	FileReader fileReader = new FileReader(file);\n" + 
3462
		"	           ^^^^^^^^^^\n" + 
3463
		"Potentially leaking resource 'fileReader': is not closed on all paths\n" + 
3464
		"----------\n",
3465
		null,
3466
		true,
3467
		options);
3468
}
3469
// Bug 349326 - [1.7] new warning for missing try-with-resources
3470
// a method uses an AutoCloseable and closes it properly in a finally block
3471
public void test056b() {
3472
	Map options = getCompilerOptions();
3473
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3474
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3475
	this.runConformTest(
3476
		new String[] {
3477
			"X.java",
3478
			"import java.io.File;\n" +
3479
			"import java.io.FileReader;\n" +
3480
			"import java.io.IOException;\n" +
3481
			"public class X {\n" +
3482
			"    void foo() throws IOException {\n" +
3483
			"        File file = new File(\"somefile\");\n" +
3484
			"        FileReader fileReader = new FileReader(file);\n" +
3485
			"        try {\n" +
3486
			"            char[] in = new char[50];\n" +
3487
			"            fileReader.read(in);\n" +
3488
			"        } finally {\n" +
3489
			"		     fileReader.close();\n" +
3490
			"        }\n" +
3491
			"    }\n" +
3492
			"    public static void main(String[] args) {\n" +
3493
			"        try {\n" +
3494
			"            new X().foo();\n" +
3495
			"        } catch (IOException ioex) {\n" +
3496
			"            System.out.println(\"caught\");\n" +
3497
			"        }\n" +
3498
			"    }\n" +
3499
			"}\n"
3500
		},
3501
		"caught", /*output*/
3502
		null/*classLibs*/,
3503
		true/*shouldFlush*/,
3504
		null/*vmargs*/,
3505
		options,
3506
		null/*requestor*/);
3507
}
3508
// Bug 349326 - [1.7] new warning for missing try-with-resources
3509
// a method uses an AutoCloseable properly within try-with-resources.
3510
public void test056c() {
3511
	Map options = getCompilerOptions();
3512
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3513
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3514
	this.runConformTest(
3515
		new String[] {
3516
			"X.java",
3517
			"import java.io.File;\n" +
3518
			"import java.io.FileReader;\n" +
3519
			"import java.io.IOException;\n" +
3520
			"public class X {\n" +
3521
			"    void foo() throws IOException {\n" +
3522
			"        File file = new File(\"somefile\");\n" +
3523
			"        try (FileReader fileReader = new FileReader(file)) {\n" +
3524
			"            char[] in = new char[50];\n" +
3525
			"            fileReader.read(in);\n" +
3526
			"		 }\n" +
3527
			"    }\n" +
3528
			"    public static void main(String[] args) {\n" +
3529
			"        try {\n" +
3530
			"            new X().foo();\n" +
3531
			"        } catch (IOException ioex) {\n" +
3532
			"            System.out.println(\"caught\");\n" +
3533
			"        }\n" +
3534
			"    }\n" +
3535
			"}\n"
3536
		},
3537
		"caught", /*output*/
3538
		null/*classLibs*/,
3539
		true/*shouldFlush*/,
3540
		null/*vmargs*/,
3541
		options,
3542
		null/*requestor*/);
3543
}
3544
// Bug 349326 - [1.7] new warning for missing try-with-resources
3545
// a method uses two AutoCloseables (testing independent analysis)
3546
// - one closeable may be unclosed at a conditional return
3547
// - the other is only conditionally closed
3548
public void test056d() {
3549
	Map options = getCompilerOptions();
3550
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3551
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3552
	this.runNegativeTest(
3553
		new String[] {
3554
			"X.java",
3555
			"import java.io.File;\n" +
3556
			"import java.io.FileReader;\n" +
3557
			"import java.io.IOException;\n" +
3558
			"public class X {\n" +
3559
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3560
			"        File file = new File(\"somefile\");\n" +
3561
			"        char[] in = new char[50];\n" +
3562
			"        FileReader fileReader1 = new FileReader(file);\n" +
3563
			"        fileReader1.read(in);\n" +
3564
			"        FileReader fileReader2 = new FileReader(file);\n" +
3565
			"        fileReader2.read(in);\n" +
3566
			"        if (flag1) {\n" +
3567
			"            fileReader2.close();\n" +
3568
			"            return;\n" +
3569
			"        } else if (flag2) {\n" +
3570
			"            fileReader2.close();\n" +
3571
			"        }\n" +
3572
			"        fileReader1.close();\n" +
3573
			"    }\n" +
3574
			"    public static void main(String[] args) throws IOException {\n" +
3575
			"        new X().foo(false, true);\n" +
3576
			"    }\n" +
3577
			"}\n"
3578
		},
3579
		"----------\n" + 
3580
		"1. WARNING in X.java (at line 10)\n" + 
3581
		"	FileReader fileReader2 = new FileReader(file);\n" + 
3582
		"	           ^^^^^^^^^^^\n" + 
3583
		"Potentially leaking resource 'fileReader2': is not closed on all paths\n" +
3584
		"----------\n" + 
3585
		"2. ERROR in X.java (at line 14)\n" + 
3586
		"	return;\n" + 
3587
		"	^^^^^^^\n" + 
3588
		"Leaking resource \'fileReader1\': is not closed at this location\n" + 
3589
		"----------\n",
3590
		null,
3591
		true,
3592
		options);
3593
}
3594
//Bug 349326 - [1.7] new warning for missing try-with-resources
3595
//a method uses two AutoCloseables (testing independent analysis)
3596
//- one closeable may be unclosed at a conditional return
3597
//- the other is only conditionally closed
3598
public void test056d_suppress() {
3599
	Map options = getCompilerOptions();
3600
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3601
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3602
	options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
3603
	this.runNegativeTest(
3604
		new String[] {
3605
			"X.java",
3606
			"import java.io.File;\n" +
3607
			"import java.io.FileReader;\n" +
3608
			"import java.io.IOException;\n" +
3609
			"public class X {\n" +
3610
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3611
			"        @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" +
3612
			"        char[] in = new char[50];\n" +
3613
			"        FileReader fileReader1 = new FileReader(file);\n" +
3614
			"        fileReader1.read(in);\n" +
3615
			"        @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" +
3616
			"        fileReader2.read(in);\n" +
3617
			"        if (flag1) {\n" +
3618
			"            fileReader2.close();\n" +
3619
			"            return; // not suppressed\n" +
3620
			"        } else if (flag2) {\n" +
3621
			"            fileReader2.close();\n" +
3622
			"        }\n" +
3623
			"        fileReader1.close();\n" +
3624
			"    }\n" +
3625
			"    @SuppressWarnings(\"resource\") // useful suppress\n" +
3626
			"    void bar() throws IOException {\n" +
3627
			"        File file = new File(\"somefile\");\n" +
3628
			"        FileReader fileReader = new FileReader(file);\n" +
3629
			"        char[] in = new char[50];\n" +
3630
			"        fileReader.read(in);\n" +
3631
			"    }\n" +
3632
			"    public static void main(String[] args) throws IOException {\n" +
3633
			"        new X().foo(false, true);\n" +
3634
			"    }\n" +
3635
			"}\n"
3636
		},
3637
		"----------\n" + 
3638
		"1. WARNING in X.java (at line 6)\n" + 
3639
		"	@SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + 
3640
		"	                  ^^^^^^^^^^\n" + 
3641
		"Unnecessary @SuppressWarnings(\"resource\")\n" + 
3642
		"----------\n" + 
3643
		"2. ERROR in X.java (at line 14)\n" + 
3644
		"	return; // not suppressed\n" + 
3645
		"	^^^^^^^\n" + 
3646
		"Leaking resource \'fileReader1\': is not closed at this location\n" + 
3647
		"----------\n",
3648
		null,
3649
		true,
3650
		options);
3651
}
3652
// Bug 349326 - [1.7] new warning for missing try-with-resources
3653
// one method returns an AutoCleasble, a second method uses this object without ever closing it.
3654
public void test056e() {
3655
	Map options = getCompilerOptions();
3656
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3657
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3658
	this.runNegativeTest(
3659
		new String[] {
3660
			"X.java",
3661
			"import java.io.File;\n" +
3662
			"import java.io.FileReader;\n" +
3663
			"import java.io.IOException;\n" +
3664
			"public class X {\n" +
3665
			"    FileReader getReader(String filename) throws IOException {\n" +
3666
			"        File file = new File(\"somefile\");\n" +
3667
			"        FileReader fileReader = new FileReader(file);\n" +
3668
			"        return fileReader;\n" + 		// don't complain here, pass responsibility to caller
3669
			"    }\n" +
3670
			"    void foo() throws IOException {\n" +
3671
			"        FileReader reader = getReader(\"somefile\");\n" +
3672
			"        char[] in = new char[50];\n" +
3673
			"        reader.read(in);\n" +
3674
			"    }\n" +
3675
			"    public static void main(String[] args) throws IOException {\n" +
3676
			"        new X().foo();\n" +
3677
			"    }\n" +
3678
			"}\n"
3679
		},
3680
		"----------\n" + 
3681
		"1. ERROR in X.java (at line 11)\n" + 
3682
		"	FileReader reader = getReader(\"somefile\");\n" + 
3683
		"	           ^^^^^^\n" + 
3684
		"Leaking resource 'reader': is never closed\n" + 
3685
		"----------\n",
3686
		null,
3687
		true,
3688
		options);
3689
}
3690
// Bug 349326 - [1.7] new warning for missing try-with-resources
3691
// a method explicitly closes its AutoCloseable rather than using t-w-r
3692
public void test056f() {
3693
	Map options = getCompilerOptions();
3694
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3695
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3696
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3697
	this.runNegativeTest(
3698
		new String[] {
3699
			"X.java",
3700
			"import java.io.File;\n" +
3701
			"import java.io.FileReader;\n" +
3702
			"import java.io.IOException;\n" +
3703
			"public class X {\n" +
3704
			"    void foo() throws IOException {\n" +
3705
			"        File file = new File(\"somefile\");\n" +
3706
			"        FileReader fileReader = null;\n" +
3707
			"        try {\n" +
3708
			"            fileReader = new FileReader(file);\n" +
3709
			"            char[] in = new char[50];\n" +
3710
			"            fileReader.read(in);\n" +
3711
			"        } finally {\n" +
3712
			"            fileReader.close();\n" +
3713
			"        }\n" +
3714
			"    }\n" +
3715
			"    public static void main(String[] args) throws IOException {\n" +
3716
			"        new X().foo();\n" +
3717
			"    }\n" +
3718
			"}\n"
3719
		},
3720
		"----------\n" + 
3721
		"1. ERROR in X.java (at line 7)\n" + 
3722
		"	FileReader fileReader = null;\n" + 
3723
		"	           ^^^^^^^^^^\n" + 
3724
		"Resource \'fileReader\' should be managed by try-with-resource\n" + 
3725
		"----------\n",
3726
		null,
3727
		true,
3728
		options);
3729
}
3730
// Bug 349326 - [1.7] new warning for missing try-with-resources
3731
// an AutoCloseable local is re-assigned
3732
public void test056g() {
3733
	Map options = getCompilerOptions();
3734
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3735
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3736
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3737
	this.runNegativeTest(
3738
		new String[] {
3739
			"X.java",
3740
			"import java.io.File;\n" +
3741
			"import java.io.FileReader;\n" +
3742
			"import java.io.IOException;\n" +
3743
			"public class X {\n" +
3744
			"    void foo() throws IOException {\n" +
3745
			"        File file = new File(\"somefile\");\n" +
3746
			"        FileReader fileReader = new FileReader(file);\n" +
3747
			"        char[] in = new char[50];\n" +
3748
			"        fileReader.read(in);\n" +
3749
			"        fileReader = new FileReader(file);\n" +
3750
			"        fileReader.read(in);\n" +
3751
			"        fileReader.close();\n" +
3752
			"        fileReader = null;\n" +
3753
			"    }\n" +
3754
			"    public static void main(String[] args) throws IOException {\n" +
3755
			"        new X().foo();\n" +
3756
			"    }\n" +
3757
			"}\n"
3758
		},
3759
		"----------\n" + 
3760
		"1. ERROR in X.java (at line 10)\n" + 
3761
		"	fileReader = new FileReader(file);\n" + 
3762
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
3763
		"Leaking resource \'fileReader\': is not closed at this location\n" + 
3764
		"----------\n",
3765
		null,
3766
		true,
3767
		options);
3768
}
3769
// Bug 349326 - [1.7] new warning for missing try-with-resources
3770
// an AutoCloseable local is re-assigned after null-assigned
3771
public void test056g2() {
3772
	Map options = getCompilerOptions();
3773
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3774
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3775
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3776
	this.runNegativeTest(
3777
		new String[] {
3778
			"X.java",
3779
			"import java.io.File;\n" +
3780
			"import java.io.FileReader;\n" +
3781
			"import java.io.IOException;\n" +
3782
			"public class X {\n" +
3783
			"    void foo() throws IOException {\n" +
3784
			"        File file = new File(\"somefile\");\n" +
3785
			"        FileReader fileReader = new FileReader(file);\n" +
3786
			"        char[] in = new char[50];\n" +
3787
			"        fileReader.read(in);\n" +
3788
			"        fileReader = null;\n" +
3789
			"        fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here
3790
			"        fileReader.read(in);\n" +
3791
			"        fileReader.close();\n" +
3792
			"    }\n" +
3793
			"    public static void main(String[] args) throws IOException {\n" +
3794
			"        new X().foo();\n" +
3795
			"    }\n" +
3796
			"}\n"
3797
		},
3798
		"----------\n" + 
3799
		"1. ERROR in X.java (at line 10)\n" + 
3800
		"	fileReader = null;\n" + 
3801
		"	^^^^^^^^^^^^^^^^^\n" + 
3802
		"Leaking resource \'fileReader\': is not closed at this location\n" + 
3803
		"----------\n",
3804
		null,
3805
		true,
3806
		options);
3807
}
3808
// Bug 349326 - [1.7] new warning for missing try-with-resources
3809
// two AutoCloseables at different nesting levels (anonymous local type)
3810
public void test056h() {
3811
	Map options = getCompilerOptions();
3812
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3813
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3814
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3815
	this.runNegativeTest(
3816
		new String[] {
3817
			"X.java",
3818
			"import java.io.File;\n" +
3819
			"import java.io.FileReader;\n" +
3820
			"import java.io.IOException;\n" +
3821
			"public class X {\n" +
3822
			"    void foo() throws IOException {\n" +
3823
			"        final File file = new File(\"somefile\");\n" +
3824
			"        final FileReader fileReader = new FileReader(file);\n" +
3825
			"        char[] in = new char[50];\n" +
3826
			"        fileReader.read(in);\n" +
3827
			"        new Runnable() {\n public void run() {\n" +
3828
			"            try {\n" +
3829
			"                fileReader.close();\n" +
3830
			"                FileReader localReader = new FileReader(file);\n" +
3831
			"            } catch (IOException ex) { /* nop */ }\n" +
3832
			"        }}.run();\n" +
3833
			"    }\n" +
3834
			"    public static void main(String[] args) throws IOException {\n" +
3835
			"        new X().foo();\n" +
3836
			"    }\n" +
3837
			"}\n"
3838
		},
3839
		"----------\n" + 
3840
		"1. WARNING in X.java (at line 7)\n" + 
3841
		"	final FileReader fileReader = new FileReader(file);\n" + 
3842
		"	                 ^^^^^^^^^^\n" + 
3843
		"Potentially leaking resource 'fileReader': is not closed on all paths\n" + 
3844
		"----------\n" + 
3845
		"2. ERROR in X.java (at line 14)\n" + 
3846
		"	FileReader localReader = new FileReader(file);\n" + 
3847
		"	           ^^^^^^^^^^^\n" + 
3848
		"Leaking resource 'localReader': is never closed\n" + 
3849
		"----------\n",
3850
		null,
3851
		true,
3852
		options);
3853
}
3854
// Bug 349326 - [1.7] new warning for missing try-with-resources
3855
// three AutoCloseables in different blocks of the same method
3856
public void test056i() {
3857
	Map options = getCompilerOptions();
3858
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3859
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3860
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3861
	this.runNegativeTest(
3862
		new String[] {
3863
			"X.java",
3864
			"import java.io.File;\n" +
3865
			"import java.io.FileReader;\n" +
3866
			"import java.io.IOException;\n" +
3867
			"public class X {\n" +
3868
			"    void foo(boolean f1, boolean f2) throws IOException {\n" +
3869
			"        File file = new File(\"somefile\");\n" +
3870
			"        if (f1) {\n" +
3871
			"            FileReader fileReader = new FileReader(file); // err: not closed\n" +
3872
			"            char[] in = new char[50];\n" +
3873
			"            fileReader.read(in);\n" +
3874
			"            while (true) {\n" +
3875
			"                 FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
3876
			"                 loopReader.close();" +
3877
			"                 break;\n" +
3878
			"            }\n" +
3879
			"        } else {\n" +
3880
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
3881
			"            if (f2)\n" +
3882
			"                fileReader.close();\n" +
3883
			"        }\n" +
3884
			"    }\n" +
3885
			"    public static void main(String[] args) throws IOException {\n" +
3886
			"        new X().foo(true, true);\n" +
3887
			"    }\n" +
3888
			"}\n"
3889
		},
3890
		"----------\n" + 
3891
		"1. ERROR in X.java (at line 8)\n" + 
3892
		"	FileReader fileReader = new FileReader(file); // err: not closed\n" + 
3893
		"	           ^^^^^^^^^^\n" + 
3894
		"Leaking resource 'fileReader': is never closed\n" + 
3895
		"----------\n" + 
3896
		"2. WARNING in X.java (at line 16)\n" + 
3897
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3898
		"	           ^^^^^^^^^^\n" + 
3899
		"Potentially leaking resource 'fileReader': is not closed on all paths\n" + 
3900
		"----------\n",
3901
		null,
3902
		true,
3903
		options);
3904
}
3905
// Bug 349326 - [1.7] new warning for missing try-with-resources
3906
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
3907
public void test056j() {
3908
	Map options = getCompilerOptions();
3909
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3910
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3911
	this.runNegativeTest(
3912
		new String[] {
3913
			"X.java",
3914
			"import java.io.File;\n" +
3915
			"import java.io.FileReader;\n" +
3916
			"import java.io.IOException;\n" +
3917
			"public class X {\n" +
3918
			"    void foo() throws IOException {\n" +
3919
			"        File file = new File(\"somefile\");\n" +
3920
			"        FileReader fileReader = new FileReader(file);\n" +
3921
			"        read(fileReader);\n" +
3922
			"    }\n" +
3923
			"    void read(FileReader reader) { }\n" +
3924
			"    public static void main(String[] args) throws IOException {\n" +
3925
			"        new X().foo();\n" +
3926
			"    }\n" +
3927
			"}\n"
3928
		},
3929
		"----------\n" + 
3930
		"1. ERROR in X.java (at line 7)\n" + 
3931
		"	FileReader fileReader = new FileReader(file);\n" + 
3932
		"	           ^^^^^^^^^^\n" + 
3933
		"Potentially leaking resource 'fileReader': is not closed on all paths\n" + 
3934
		"----------\n",
3935
		null,
3936
		true,
3937
		options);
3938
}
3939
// Bug 349326 - [1.7] new warning for missing try-with-resources
3940
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
3941
public void test056jconditional() {
3942
	Map options = getCompilerOptions();
3943
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3944
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3945
	this.runNegativeTest(
3946
		new String[] {
3947
			"X.java",
3948
			"import java.io.File;\n" +
3949
			"import java.io.FileReader;\n" +
3950
			"import java.io.IOException;\n" +
3951
			"public class X {\n" +
3952
			"    void foo(boolean b) throws IOException {\n" +
3953
			"        File file = new File(\"somefile\");\n" +
3954
			"        FileReader fileReader = new FileReader(file);\n" +
3955
			"        synchronized (b ? this : new X()) {\n" +
3956
			"            new ReadDelegator(fileReader);\n" +
3957
			"        }\n" +
3958
			"    }\n" +
3959
			"    class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" +
3960
			"    public static void main(String[] args) throws IOException {\n" +
3961
			"        new X().foo(true);\n" +
3962
			"    }\n" +
3963
			"}\n"
3964
		},
3965
		"----------\n" + 
3966
		"1. ERROR in X.java (at line 7)\n" + 
3967
		"	FileReader fileReader = new FileReader(file);\n" + 
3968
		"	           ^^^^^^^^^^\n" + 
3969
		"Potentially leaking resource 'fileReader': is not closed on all paths\n" + 
3970
		"----------\n",
3971
		null,
3972
		true,
3973
		options);
3974
}
3975
// Bug 349326 - [1.7] new warning for missing try-with-resources
3976
// many locals, some are AutoCloseable.
3977
// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3,
3978
// doing so would create false positives.
3979
public void test056k() {
3980
	Map options = getCompilerOptions();
3981
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3982
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3983
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3984
	this.runNegativeTest(
3985
		new String[] {
3986
			"X.java",
3987
			"import java.io.File;\n" +
3988
			"import java.io.FileReader;\n" +
3989
			"import java.io.IOException;\n" +
3990
			"public class X {\n" +
3991
			"    void foo() throws IOException {\n" +
3992
			"        int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" +
3993
			"            i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" +
3994
			"            i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" +
3995
			"            i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" +
3996
			"            i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" +
3997
			"        File file = new File(\"somefile\");\n" +
3998
			"        FileReader ra1 = null, ra2 = null;\n" +
3999
			"        try {\n" +
4000
			"            ra1 = new FileReader(file);\n" +
4001
			"            ra2 = new FileReader(file);\n" +
4002
			"            FileReader ra3 = new FileReader(file);\n" +
4003
			"            char[] in = new char[50];\n" +
4004
			"            ra1.read(in);\n" +
4005
			"            ra2.read(in);\n" +
4006
			"            ra3.close();\n" +
4007
			"        } finally {\n" +
4008
			"            ra1.close();\n" +
4009
			"        }\n" +
4010
			"        int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits
4011
			"        FileReader rb1 = null, rb2 = null;\n" +
4012
			"        try {\n" +
4013
			"            rb1 = new FileReader(file);\n" +
4014
			"            rb2 = new FileReader(file);\n" +
4015
			"            FileReader rb3 = new FileReader(file);\n" +
4016
			"            char[] in = new char[50];\n" +
4017
			"            rb1.read(in);\n" +
4018
			"            rb2.read(in);\n" +
4019
			"            rb3.close();\n" +
4020
			"        } finally {\n" +
4021
			"            rb1.close();\n" +
4022
			"        }\n" +
4023
			"    }\n" +
4024
			"    public static void main(String[] args) throws IOException {\n" +
4025
			"        new X().foo();\n" +
4026
			"    }\n" +
4027
			"}\n"
4028
		},
4029
		"----------\n" + 
4030
		"1. ERROR in X.java (at line 12)\n" + 
4031
		"	FileReader ra1 = null, ra2 = null;\n" + 
4032
		"	           ^^^\n" + 
4033
		"Resource \'ra1\' should be managed by try-with-resource\n" + 
4034
		"----------\n" + 
4035
		"2. ERROR in X.java (at line 15)\n" + 
4036
		"	ra2 = new FileReader(file);\n" + 
4037
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4038
		"Leaking resource 'ra2': is never closed\n" + 
4039
		"----------\n" + 
4040
		"3. ERROR in X.java (at line 16)\n" + 
4041
		"	FileReader ra3 = new FileReader(file);\n" + 
4042
		"	           ^^^\n" + 
4043
		"Resource \'ra3\' should be managed by try-with-resource\n" +
4044
		"----------\n" + 
4045
		"4. ERROR in X.java (at line 25)\n" + 
4046
		"	FileReader rb1 = null, rb2 = null;\n" + 
4047
		"	           ^^^\n" + 
4048
		"Resource \'rb1\' should be managed by try-with-resource\n" + 
4049
		"----------\n" + 
4050
		"5. ERROR in X.java (at line 28)\n" + 
4051
		"	rb2 = new FileReader(file);\n" + 
4052
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4053
		"Leaking resource 'rb2': is never closed\n" + 
4054
		"----------\n" + 
4055
		"6. ERROR in X.java (at line 29)\n" + 
4056
		"	FileReader rb3 = new FileReader(file);\n" + 
4057
		"	           ^^^\n" + 
4058
		"Resource \'rb3\' should be managed by try-with-resource\n" + 
4059
		"----------\n",
4060
		null,
4061
		true,
4062
		options);
4063
}
4064
// Bug 349326 - [1.7] new warning for missing try-with-resources
4065
// various non-problems
4066
public void test056l() {
4067
	Map options = getCompilerOptions();
4068
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4069
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4070
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
4071
	this.runNegativeTest(
4072
		new String[] {
4073
			"X.java",
4074
			"import java.io.File;\n" +
4075
			"import java.io.FileReader;\n" +
4076
			"import java.io.IOException;\n" +
4077
			"public class X {\n" +
4078
			"    X(FileReader r0) {}\n" + // don't complain against argument
4079
			"    FileReader getReader() { return null; }\n" +
4080
			"    void foo(FileReader r1) throws IOException {\n" +
4081
			"        FileReader fileReader = getReader();\n" +
4082
			"        if (fileReader == null)\n" +
4083
			"            return;\n" + // don't complain, resource is actually null
4084
			"        FileReader r3 = getReader();\n" +
4085
			"        if (r3 == null)\n" +
4086
			"            r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null
4087
			"        try {\n" +
4088
			"            char[] in = new char[50];\n" +
4089
			"            fileReader.read(in);\n" +
4090
			"            r1.read(in);\n" +
4091
			"        } finally {\n" +
4092
			"            fileReader.close();\n" +
4093
			"            r3.close();\n" +  // the effect of this close() call might be spoiled by exception in fileReader.close() above
4094
			"        }\n" +
4095
			"    }\n" +
4096
			"    public static void main(String[] args) throws IOException {\n" +
4097
			"        FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" +
4098
			"        new X(r2).foo(new FileReader(new File(\"notthere\")));\n" +
4099
			"    }\n" +
4100
			"}\n"
4101
		},
4102
		"----------\n" + 
4103
		"1. ERROR in X.java (at line 8)\n" + 
4104
		"	FileReader fileReader = getReader();\n" + 
4105
		"	           ^^^^^^^^^^\n" + 
4106
		"Resource \'fileReader\' should be managed by try-with-resource\n" + 
4107
		"----------\n" + 
4108
		"2. ERROR in X.java (at line 11)\n" + 
4109
		"	FileReader r3 = getReader();\n" + 
4110
		"	           ^^\n" + 
4111
		"Potentially leaking resource 'r3': is not closed on all paths\n" +
4112
		"----------\n" + 
4113
		"3. ERROR in X.java (at line 24)\n" + 
4114
		"	FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + 
4115
		"	           ^^\n" + 
4116
		"Potentially leaking resource 'r2': is not closed on all paths\n" + 
4117
		"----------\n",
4118
		null,
4119
		true,
4120
		options);
4121
}
4122
// Bug 349326 - [1.7] new warning for missing try-with-resources
4123
// nested try with early exit
4124
public void test056m() {
4125
	Map options = getCompilerOptions();
4126
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4127
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4128
	this.runConformTest(
4129
		new String[] {
4130
			"X.java",
4131
			"import java.io.File;\n" +
4132
			"import java.io.FileReader;\n" +
4133
			"import java.io.IOException;\n" +
4134
			"public class X {\n" +
4135
			"    void foo() {\n" +
4136
			"        File file = new File(\"somefile\");" +
4137
			"        try {\n" +
4138
			"            FileReader fileReader = new FileReader(file);\n" +
4139
			"            try {\n" +
4140
			"                char[] in = new char[50];\n" +
4141
			"                if (fileReader.read(in)==0)\n" +
4142
			"                    return;\n" +
4143
			"            } finally {\n" +
4144
			"		         fileReader.close();\n" +
4145
			"            }\n" +
4146
			"        } catch (IOException e) {\n" +
4147
			"            System.out.println(\"caught\");\n" +
4148
			"        }\n" +
4149
			"    }\n" +
4150
			"    public static void main(String[] args) {\n" +
4151
			"        new X().foo();\n" +
4152
			"    }\n" +
4153
			"}\n"
4154
		},
4155
		"caught", /*output*/
4156
		null/*classLibs*/,
4157
		true/*shouldFlush*/,
4158
		null/*vmargs*/,
4159
		options,
4160
		null/*requestor*/);
4161
}
4162
// Bug 349326 - [1.7] new warning for missing try-with-resources
4163
// nested try should not interfere with earlier analysis.
4164
public void test056n() {
4165
	Map options = getCompilerOptions();
4166
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4167
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4168
	this.runConformTest(
4169
		new String[] {
4170
			"X.java",
4171
			"import java.io.File;\n" +
4172
			"import java.io.FileReader;\n" +
4173
			"import java.io.IOException;\n" +
4174
			"import java.io.FileNotFoundException;\n" +
4175
			"public class X {\n" +
4176
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4177
			"		FileReader fr1 = new FileReader(someFile);\n" + 
4178
			"		try {\n" + 
4179
			"			fr1.read(buf);\n" + 
4180
			"		} finally {\n" + 
4181
			"			fr1.close();\n" + 
4182
			"		}\n" + 
4183
			"		try {\n" + 
4184
			"			FileReader fr3 = new FileReader(someFile);\n" + 
4185
			"			try {\n" + 
4186
			"			} finally {\n" + 
4187
			"				fr3.close();\n" + 
4188
			"			}\n" + 
4189
			"		} catch (IOException e) {\n" + 
4190
			"		}\n" + 
4191
			"	 }\n" +
4192
			"    public static void main(String[] args) throws IOException {\n" +
4193
			"        try {\n" +
4194
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4195
			"        } catch (FileNotFoundException e) {\n" +
4196
			"            System.out.println(\"caught\");\n" +
4197
			"        }\n" +
4198
			"    }\n" +
4199
			"}\n"
4200
		},
4201
		"caught", /*output*/
4202
		null/*classLibs*/,
4203
		true/*shouldFlush*/,
4204
		null/*vmargs*/,
4205
		options,
4206
		null/*requestor*/);
4207
}
4208
// Bug 349326 - [1.7] new warning for missing try-with-resources
4209
// if close is guarded by null check this should still be recognized as definitely closed
4210
public void test056o() {
4211
	Map options = getCompilerOptions();
4212
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4213
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
4214
	this.runConformTest(
4215
		new String[] {
4216
			"X.java",
4217
			"import java.io.File;\n" +
4218
			"import java.io.FileReader;\n" +
4219
			"import java.io.IOException;\n" +
4220
			"import java.io.FileNotFoundException;\n" +
4221
			"public class X {\n" +
4222
			"    void foo(File someFile, char[] buf) throws IOException {\n" + 
4223
			"		FileReader fr1 = null;\n" + 
4224
			"		try {\n" +
4225
			"           fr1 = new FileReader(someFile);" + 
4226
			"			fr1.read(buf);\n" + 
4227
			"		} finally {\n" + 
4228
			"			if (fr1 != null)\n" +
4229
			"               try {\n" +
4230
			"                   fr1.close();\n" +
4231
			"               } catch (IOException e) { /*do nothing*/ }\n" + 
4232
			"		}\n" + 
4233
			"	 }\n" +
4234
			"    public static void main(String[] args) throws IOException {\n" +
4235
			"        try {\n" +
4236
			"            new X().foo(new File(\"missing\"), new char[100]);\n" +
4237
			"        } catch (FileNotFoundException e) {\n" +
4238
			"            System.out.println(\"caught\");\n" +
4239
			"        }\n" +
4240
			"    }\n" +
4241
			"}\n"
4242
		},
4243
		"caught", /*output*/
4244
		null/*classLibs*/,
4245
		true/*shouldFlush*/,
4246
		null/*vmargs*/,
4247
		options,
4248
		null/*requestor*/);
4249
}
4250
// Bug 349326 - [1.7] new warning for missing try-with-resources
4251
// a method uses an AutoCloseable without ever closing it, type from a type variable
4252
public void test056p() {
4253
	Map options = getCompilerOptions();
4254
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
4255
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
4256
	this.runNegativeTest(
4257
		new String[] {
4258
			"X.java",
4259
			"import java.io.File;\n" +
4260
			"import java.io.FileReader;\n" +
4261
			"import java.io.Reader;\n" +
4262
			"import java.io.IOException;\n" +
4263
			"public abstract class X <T extends Reader> {\n" +
4264
			"    void foo() throws IOException {\n" +
4265
			"        File file = new File(\"somefile\");\n" +
4266
			"        T fileReader = newReader(file);\n" +
4267
			"        char[] in = new char[50];\n" +
4268
			"        fileReader.read(in);\n" +
4269
			"    }\n" +
4270
			"    abstract T newReader(File file) throws IOException;\n" +
4271
			"    public static void main(String[] args) throws IOException {\n" +
4272
			"        new X<FileReader>() {\n" +
4273
			"            FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" +
4274
			"        }.foo();\n" +
4275
			"    }\n" +
4276
			"}\n"
4277
		},
4278
		"----------\n" + 
4279
		"1. ERROR in X.java (at line 8)\n" + 
4280
		"	T fileReader = newReader(file);\n" + 
4281
		"	  ^^^^^^^^^^\n" + 
4282
		"Leaking resource 'fileReader': is never closed\n" +
4283
		"----------\n",
4284
		null,
4285
		true,
4286
		options);
4287
}
4288
// Bug 349326 - [1.7] new warning for missing try-with-resources
4289
// closed in dead code
4290
public void test056q() {
4291
	Map options = getCompilerOptions();
4292
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4293
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4294
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4295
	this.runNegativeTest(
4296
		new String[] {
4297
			"X.java",
4298
			"import java.io.File;\n" +
4299
			"import java.io.FileReader;\n" +
4300
			"import java.io.IOException;\n" +
4301
			"public class X {\n" +
4302
			"    void foo() throws IOException {\n" +
4303
			"        File file = new File(\"somefile\");\n" +
4304
			"        FileReader fileReader = new FileReader(file);\n" +
4305
			"        char[] in = new char[50];\n" +
4306
			"        fileReader.read(in);\n" +
4307
			"        if (2*2 == 4)\n" +
4308
			"        	return;\n" +
4309
			"        fileReader.close();\n" +
4310
			"    }\n" +
4311
			"    public static void main(String[] args) throws IOException {\n" +
4312
			"        new X().foo();\n" +
4313
			"    }\n" +
4314
			"}\n"
4315
		},
4316
		"----------\n" + 
4317
		"1. ERROR in X.java (at line 7)\n" + 
4318
		"	FileReader fileReader = new FileReader(file);\n" + 
4319
		"	           ^^^^^^^^^^\n" + 
4320
		"Leaking resource \'fileReader\': is never closed\n" + 
4321
		"----------\n" + 
4322
		"2. WARNING in X.java (at line 10)\n" + 
4323
		"	if (2*2 == 4)\n" + 
4324
		"	    ^^^^^^^^\n" + 
4325
		"Comparing identical expressions\n" + 
4326
		"----------\n" + 
4327
		"3. WARNING in X.java (at line 12)\n" + 
4328
		"	fileReader.close();\n" + 
4329
		"	^^^^^^^^^^^^^^^^^^\n" + 
4330
		"Dead code\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 test056r() {
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
	options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR);
4344
	this.runNegativeTest(
4345
		new String[] {
4346
			"X.java",
4347
			"import java.io.File;\n" +
4348
			"import java.io.FileReader;\n" +
4349
			"import java.io.IOException;\n" +
4350
			"public class X {\n" +
4351
			"    void foo() throws IOException {\n" +
4352
			"        File file = new File(\"somefile\");\n" +
4353
			"        FileReader fr = new FileReader(file);\n" +
4354
			"  		 Object b = null;\n" + 
4355
			"        fr.close();\n" + 
4356
			"        if (b != null) {\n" + 
4357
			"            fr = new FileReader(file);\n" + 
4358
			"            return;\n" + 
4359
			"        } else {\n" + 
4360
			"            System.out.print(42);\n" + 
4361
			"        }\n" + 
4362
			"        return;     // Should not complain about fr\n" +
4363
			"    }\n" +
4364
			"    public static void main(String[] args) throws IOException {\n" +
4365
			"        new X().foo();\n" +
4366
			"    }\n" +
4367
			"}\n"
4368
		},
4369
		"----------\n" + 
4370
		"1. ERROR in X.java (at line 10)\n" + 
4371
		"	if (b != null) {\n" + 
4372
		"            fr = new FileReader(file);\n" + 
4373
		"            return;\n" + 
4374
		"        } else {\n" + 
4375
		"	               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4376
		"Dead code\n" + 
4377
		"----------\n" + 
4378
		"2. WARNING in X.java (at line 13)\n" + 
4379
		"	} else {\n" + 
4380
		"            System.out.print(42);\n" + 
4381
		"        }\n" + 
4382
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
4383
		"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + 
4384
		"----------\n",
4385
		null,
4386
		true,
4387
		options);
4388
}
4389
// Bug 349326 - [1.7] new warning for missing try-with-resources
4390
// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation
4391
public void test056s() {
4392
	Map options = getCompilerOptions();
4393
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
4394
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
4395
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
4396
	this.runNegativeTest(
4397
		new String[] {
4398
			"X.java",
4399
			"import java.io.File;\n" + 
4400
			"import java.io.FileReader;\n" + 
4401
			"import java.io.IOException;\n" + 
4402
			"public class X {\n" + 
4403
			"    void foo() throws IOException {\n" + 
4404
			"        File file = new File(\"somefile\");\n" + 
4405
			"        try (FileReader fileReader = new FileReader(file);) {\n" + 
4406
			"            char[] in = new char[50];\n" + 
4407
			"            fileReader.read(in);\n" + 
4408
			"            fileReader = new FileReader(file);  // debug here\n" + 
4409
			"            fileReader.read(in);\n" + 
4410
			"        }\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
		"	fileReader = new FileReader(file);  // debug here\n" + 
4420
		"	^^^^^^^^^^\n" + 
4421
		"The resource fileReader of a try-with-resources statement cannot be assigned\n" + 
4422
		"----------\n",
4423
		null,
4424
		true,
4425
		options);
4426
}
3383
public static Class testClass() {
4427
public static Class testClass() {
3384
	return TryWithResourcesStatementTest.class;
4428
	return TryWithResourcesStatementTest.class;
3385
}
4429
}

Return to bug 349326