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 (+11 lines)
Lines 1394-1399 Link Here
1394
	int UnhandledExceptionOnAutoClose =  TypeRelated + 882;
1394
	int UnhandledExceptionOnAutoClose =  TypeRelated + 882;
1395
	/** @since 3.7 */
1395
	/** @since 3.7 */
1396
	int DiamondNotBelow17 =  TypeRelated + 883;
1396
	int DiamondNotBelow17 =  TypeRelated + 883;
1397
	/** @since 3.7 */
1398
	int PotentiallyUnclosedCloseable = Internal + 884;
1399
	/** @since 3.7 */
1400
	int PotentiallyUnclosedCloseableAtExit = Internal + 885;
1401
	/** @since 3.7 */
1402
	int UnclosedCloseable = Internal + 886;
1403
	/** @since 3.7 */
1404
	int UnclosedCloseableAtExit = Internal + 887;
1405
	/** @since 3.7 */
1406
	int ExplicitlyClosedAutoCloseable = Internal + 888;
1407
1397
	/**
1408
	/**
1398
	 * External problems -- These are problems defined by other plugins
1409
	 * External problems -- These are problems defined by other plugins
1399
	 */
1410
	 */
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (+23 lines)
Lines 48-53 Link Here
48
	if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
48
	if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
49
		this.expression.checkNPE(currentScope, flowContext, flowInfo);
49
		this.expression.checkNPE(currentScope, flowContext, flowInfo);
50
	}
50
	}
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(trackerBinding)) 
57
				currentScope.problemReporter().unclosedCloseable(local.closeTracker, this);
58
			else if (flowInfo.isPotentiallyNull(trackerBinding)) 
59
				currentScope.problemReporter().potentiallyUnclosedCloseable(local.closeTracker, this);
60
		}
61
		if (FakedTrackingVariable.isAutoCloseable(this.expression.resolvedType)) {
62
			if (local.closeTracker != null && local.closeTracker.isInsideTryWithResources) { 
63
				// re-assigning resource of try-with-resources is a different error
64
			} else {
65
				// new value is AutoCloseable, start tracking, possibly re-using existing tracker var:
66
				if (trackerBinding == null) {
67
					local.closeTracker = new FakedTrackingVariable(local.declaringScope, this, local.name);
68
					trackerBinding = local.closeTracker.binding;
69
				}
70
				flowInfo.markAsDefinitelyNull(trackerBinding);
71
			}
72
		}
73
	}
51
	flowInfo = ((Reference) this.lhs)
74
	flowInfo = ((Reference) this.lhs)
52
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
75
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
53
		.unconditionalInits();
76
		.unconditionalInits();
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Block.java (+2 lines)
Lines 36-41 Link Here
36
			flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
36
			flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
37
		}
37
		}
38
	}
38
	}
39
	if (this.explicitDeclarations > 0) // if block has its own scope analyze tracking vars now:
40
		this.scope.checkUnclosedCloseables(flowInfo, flowContext, null);
39
	return flowInfo;
41
	return flowInfo;
40
}
42
}
41
/**
43
/**
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java (+101 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
 *     GK Software AG - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
12
13
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
14
import org.eclipse.jdt.internal.compiler.impl.Constant;
15
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
16
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
17
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
18
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
19
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
20
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
21
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
22
23
/**
24
 * A faked local variable declaration used for keeping track of data flows of a
25
 * special variable. Certain events will be recorded by changing the null info
26
 * for this variable.
27
 * 
28
 * @author Stephan Herrmann
29
 */
30
public class FakedTrackingVariable extends LocalDeclaration {
31
32
	/** If resource is already managed by try-with-resources don't complain. */
33
	public boolean isInsideTryWithResources;
34
35
	/** 
36
	 * If close() is invoked from a nested method (inside a local type) 
37
	 * report remaining problems only as potential.
38
	 */
39
	public boolean closedInNestedMethod; 
40
41
	/** If a problem has already been reported don't complain again. */
42
	public boolean hasReportedProblem;
43
44
	MethodScope methodScope; // designates the method declaring this variable
45
46
	public FakedTrackingVariable(BlockScope currentScope, Statement location, char[] name) {
47
		super(name, location.sourceStart, location.sourceEnd);
48
		this.type = new SingleTypeReference(
49
				TypeConstants.OBJECT,
50
				((long)this.sourceStart <<32)+this.sourceEnd);
51
		this.methodScope = currentScope.methodScope();
52
		resolve(currentScope);
53
	}
54
	
55
	public void generateCode(BlockScope currentScope, CodeStream codeStream)
56
	{ /* NOP - this variable is completely dummy, ie. for analysis only. */ }
57
58
	public void resolve (BlockScope scope) {
59
		// only need the binding, which is used as reference in FlowInfo methods.
60
		this.binding = new LocalVariableBinding(
61
				this.name,
62
				scope.getJavaLangObject(),  // dummy, just needs to be a reference type
63
				0,
64
				false);
65
		this.binding.setConstant(Constant.NotAConstant);
66
		this.binding.useFlag = LocalVariableBinding.USED;
67
		// use a free slot without assigning it:
68
		this.binding.id = scope.registerTrackingVariable(this);
69
	}
70
71
	/**
72
	 * If expression resolves to a local variable binding of type AutoCloseable,
73
	 * answer the variable that tracks closing of that local, creating it if needed.
74
	 * @param expression
75
	 * @return a new {@link FakedTrackingVariable} or null.
76
	 */
77
	public static FakedTrackingVariable getCloseTrackingVariable(Expression expression) {
78
		if (expression instanceof SingleNameReference) {
79
			SingleNameReference name = (SingleNameReference) expression;
80
			if (name.binding instanceof LocalVariableBinding) {
81
				LocalVariableBinding local = (LocalVariableBinding)name.binding;
82
				if (local.closeTracker != null)
83
					return local.closeTracker;
84
				if (!isAutoCloseable(expression.resolvedType))
85
					return null;
86
				// tracking var doesn't yet exist. This happens in finally block
87
				// which is analyzed before the corresponding try block
88
				Statement location = local.declaration;
89
				return local.closeTracker
90
						= new FakedTrackingVariable(local.declaringScope, location, name.token);
91
			}
92
		}
93
		return null;
94
	}
95
96
	/** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */
97
	public static boolean isAutoCloseable(TypeBinding typeBinding) {
98
		return typeBinding instanceof ReferenceBinding
99
			&& ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable);
100
	}
101
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (+4 lines)
Lines 71-76 Link Here
71
	if ((this.initialization.implicitConversion & TypeIds.UNBOXING) != 0) {
71
	if ((this.initialization.implicitConversion & TypeIds.UNBOXING) != 0) {
72
		this.initialization.checkNPE(currentScope, flowContext, flowInfo);
72
		this.initialization.checkNPE(currentScope, flowContext, flowInfo);
73
	}
73
	}
74
	if (FakedTrackingVariable.isAutoCloseable(this.initialization.resolvedType)) {
75
		this.binding.closeTracker = new FakedTrackingVariable(currentScope, this, this.name);
76
		flowInfo.markAsDefinitelyNull(this.binding.closeTracker.binding);
77
	}
74
	
78
	
75
	flowInfo =
79
	flowInfo =
76
		this.initialization
80
		this.initialization
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (+22 lines)
Lines 42-47 Link Here
42
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
42
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
43
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
43
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
44
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
44
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
45
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
45
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
46
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
46
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
47
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
47
48
Lines 64-69 Link Here
64
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
65
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
65
	boolean nonStatic = !this.binding.isStatic();
66
	boolean nonStatic = !this.binding.isStatic();
66
	flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
67
	flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
68
	// recording the closing of AutoCloseable resources:
69
	if (CharOperation.equals(TypeConstants.CLOSE, this.selector)) 
70
	{
71
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.receiver);
72
		if (trackingVariable != null) { // null happens if receiver is not a local variable or not an AutoCloseable
73
			if (trackingVariable.methodScope == currentScope.methodScope()) {
74
				flowInfo.markAsDefinitelyNonNull(trackingVariable.binding);
75
				if (flowContext.initsOnFinally != null)
76
					flowContext.initsOnFinally.markAsDefinitelyNonNull(trackingVariable.binding);
77
			} else {
78
				trackingVariable.closedInNestedMethod = true;
79
			}
80
		}
81
	}
67
	if (nonStatic) {
82
	if (nonStatic) {
68
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
83
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
69
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
84
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
Lines 84-89 Link Here
84
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
99
			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
85
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
100
				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
86
			}
101
			}
102
			FakedTrackingVariable trackVar = FakedTrackingVariable.getCloseTrackingVariable(this.arguments[i]);
103
			if (trackVar != null) {
104
				// insert info that the tracked resource *may* be closed (by the target method, i.e.)
105
				FlowInfo infoResourceIsClosed = flowInfo.copy();
106
				infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding);
107
				flowInfo = FlowInfo.conditional(flowInfo, infoResourceIsClosed);
108
			}
87
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
109
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
88
		}
110
		}
89
	}
111
	}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java (+1 lines)
Lines 134-139 Link Here
134
				}
134
				}
135
					
135
					
136
			}
136
			}
137
			this.scope.checkUnclosedCloseables(flowInfo, methodContext, null);
137
		} catch (AbortMethod e) {
138
		} catch (AbortMethod e) {
138
			this.ignoreFurtherInvestigation = true;
139
			this.ignoreFurtherInvestigation = true;
139
		}
140
		}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (+8 lines)
Lines 40-45 Link Here
40
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
40
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
41
			this.expression.checkNPE(currentScope, flowContext, flowInfo);
41
			this.expression.checkNPE(currentScope, flowContext, flowInfo);
42
		}
42
		}
43
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
44
		if (trackingVariable != null) {
45
			// don't report issues concerning this local, since by returning
46
			// the method passes the responsibility to the caller:
47
			flowInfo.markAsDefinitelyNonNull(trackingVariable.binding);
48
			trackingVariable.hasReportedProblem = true;
49
		}
43
	}
50
	}
44
	this.initStateIndex =
51
	this.initStateIndex =
45
		currentScope.methodScope().recordInitializationStates(flowInfo);
52
		currentScope.methodScope().recordInitializationStates(flowInfo);
Lines 104-109 Link Here
104
			this.expression.bits |= ASTNode.IsReturnedValue;
111
			this.expression.bits |= ASTNode.IsReturnedValue;
105
		}
112
		}
106
	}
113
	}
114
	currentScope.checkUnclosedCloseables(flowInfo, null/*ignore exception exits from flowContext*/, this);
107
	return FlowInfo.DEAD_END;
115
	return FlowInfo.DEAD_END;
108
}
116
}
109
117
(-)compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java (-4 / +21 lines)
Lines 120-127 Link Here
120
120
121
		for (int i = 0, max = this.resources.length; i < max; i++) {
121
		for (int i = 0, max = this.resources.length; i < max; i++) {
122
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
122
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
123
			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
123
			LocalVariableBinding resourceBinding = this.resources[i].binding;
124
			TypeBinding type = this.resources[i].binding.type;
124
			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
125
			if (resourceBinding.closeTracker != null) {
126
				resourceBinding.closeTracker.isInsideTryWithResources = true;
127
				flowInfo.markAsDefinitelyNonNull(resourceBinding.closeTracker.binding);
128
			} 
129
			TypeBinding type = resourceBinding.type;
125
			if (type != null && type.isValidBinding()) {
130
			if (type != null && type.isValidBinding()) {
126
				ReferenceBinding binding = (ReferenceBinding) type;
131
				ReferenceBinding binding = (ReferenceBinding) type;
127
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
132
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
Lines 227-232 Link Here
227
			this.scope.problemReporter().finallyMustCompleteNormally(this.finallyBlock);
232
			this.scope.problemReporter().finallyMustCompleteNormally(this.finallyBlock);
228
		}
233
		}
229
		this.subRoutineInits = subInfo;
234
		this.subRoutineInits = subInfo;
235
230
		// process the try block in a context handling the local exceptions.
236
		// process the try block in a context handling the local exceptions.
231
		ExceptionHandlingFlowContext handlingContext =
237
		ExceptionHandlingFlowContext handlingContext =
232
			new ExceptionHandlingFlowContext(
238
			new ExceptionHandlingFlowContext(
Lines 245-252 Link Here
245
251
246
		for (int i = 0, max = this.resources.length; i < max; i++) {
252
		for (int i = 0, max = this.resources.length; i < max; i++) {
247
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
253
			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
248
			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
254
			LocalVariableBinding resourceBinding = this.resources[i].binding;
249
			TypeBinding type = this.resources[i].binding.type;
255
			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
256
			if (resourceBinding.closeTracker != null) {
257
				resourceBinding.closeTracker.isInsideTryWithResources = true;
258
				flowInfo.markAsDefinitelyNonNull(resourceBinding.closeTracker.binding);
259
			} 
260
			TypeBinding type = resourceBinding.type;
250
			if (type != null && type.isValidBinding()) {
261
			if (type != null && type.isValidBinding()) {
251
				ReferenceBinding binding = (ReferenceBinding) type;
262
				ReferenceBinding binding = (ReferenceBinding) type;
252
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
263
				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
Lines 267-272 Link Here
267
				this.bits |= ASTNode.IsTryBlockExiting;
278
				this.bits |= ASTNode.IsTryBlockExiting;
268
		}
279
		}
269
280
281
		// superimpose status for tracking variables:
282
		//   don't complain on initsOnException if finally has a better state.
283
		long trackVarsMask = currentScope.getTrackVarsMask();
284
		if (trackVarsMask != 0)
285
			flowContext.replaceNullInfoForExceptionExits(trackVarsMask, subInfo);
286
270
		// check unreachable catch blocks
287
		// check unreachable catch blocks
271
		handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);
288
		handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);
272
289
(-)compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java (-2 / +35 lines)
Lines 16-32 Link Here
16
16
17
import java.util.ArrayList;
17
import java.util.ArrayList;
18
18
19
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
20
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
19
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
20
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
21
import org.eclipse.jdt.internal.compiler.ast.Argument;
21
import org.eclipse.jdt.internal.compiler.ast.Argument;
22
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
23
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
22
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
24
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
23
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
25
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
24
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
25
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
26
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
26
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
27
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
27
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
28
import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
28
import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
29
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
29
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
30
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
30
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
31
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
31
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
32
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
32
import org.eclipse.jdt.internal.compiler.lookup.Scope;
33
import org.eclipse.jdt.internal.compiler.lookup.Scope;
Lines 302-305 Link Here
302
	}
303
	}
303
	return null;
304
	return null;
304
}
305
}
306
/**
307
 * {@inheritDoc}
308
 */
309
public void replaceNullInfoForExceptionExits(long mask, FlowInfo otherInfo) {
310
	if (mask == 0 || this.initsOnExceptions == null) return;
311
	for (int i = 0; i < this.initsOnExceptions.length; i++)
312
		this.initsOnExceptions[i].replaceNullInfo(mask, otherInfo.unconditionalCopy());
313
}
314
/**
315
 * Get the most unsafe null status from any of flowInfo or the initsOnException of flowContext (if existent).
316
 * @param local
317
 * @param flowInfo
318
 * @param flowContext
319
 * @return a bitset from the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}.
320
 */
321
public static int getMaxUnsafeNullStatus(LocalVariableBinding local, FlowInfo flowInfo, FlowContext flowContext) {
322
	int status = flowInfo.nullStatus(local);
323
	int UNSAFE_MASK = FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL;
324
	if ((status & UNSAFE_MASK) != 0)
325
		return status & UNSAFE_MASK;
326
	if (flowContext instanceof ExceptionHandlingFlowContext) {
327
		UnconditionalFlowInfo[] initsOnExceptions = ((ExceptionHandlingFlowContext) flowContext).initsOnExceptions;
328
		if (initsOnExceptions != null) {
329
			for (int i = 0; i < initsOnExceptions.length; i++) {
330
				int excStatus = initsOnExceptions[i].nullStatus(local);
331
				if ((excStatus & UNSAFE_MASK) != 0)
332
					return FlowInfo.POTENTIALLY_NULL;
333
			}
334
		}
335
	}
336
	return FlowInfo.NON_NULL;
337
}
305
}
338
}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java (-1 / +9 lines)
Lines 16-23 Link Here
16
16
17
import java.util.ArrayList;
17
import java.util.ArrayList;
18
import org.eclipse.jdt.core.compiler.CharOperation;
18
import org.eclipse.jdt.core.compiler.CharOperation;
19
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
20
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
19
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
20
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
21
import org.eclipse.jdt.internal.compiler.ast.Expression;
21
import org.eclipse.jdt.internal.compiler.ast.Expression;
22
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
22
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
23
import org.eclipse.jdt.internal.compiler.ast.Reference;
23
import org.eclipse.jdt.internal.compiler.ast.Reference;
Lines 736-739 Link Here
736
	buffer.append(individualToString()).append('\n');
736
	buffer.append(individualToString()).append('\n');
737
	return buffer.toString();
737
	return buffer.toString();
738
}
738
}
739
/** 
740
 * For all variables in mask (assumed to be FakedTrackingVariable),
741
 * replace the null info in initsOnException (if existent) 
742
 * with those given in finallyInfo.
743
 */
744
public void replaceNullInfoForExceptionExits(long trackVarsMask, FlowInfo flowInfo) { 
745
	// nothing here, overridden in ExceptionHandlingFlowContext
746
}
739
}
747
}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (-1 / +16 lines)
Lines 16-21 Link Here
16
 *******************************************************************************/
16
 *******************************************************************************/
17
package org.eclipse.jdt.internal.compiler.flow;
17
package org.eclipse.jdt.internal.compiler.flow;
18
18
19
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
20
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
20
import org.eclipse.jdt.internal.compiler.impl.Constant;
21
import org.eclipse.jdt.internal.compiler.impl.Constant;
21
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
22
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
Lines 1889-1895 Link Here
1889
	}
1890
	}
1890
	return count;
1891
	return count;
1891
}
1892
}
1892
1893
/** Replace the null info for all variables in mask by values from otherInfo. */
1894
public void replaceNullInfo(long mask, UnconditionalFlowInfo otherInfo) {
1895
	this.nullBit1 &= ~mask;
1896
	this.nullBit1 |= (otherInfo.nullBit1 & mask);
1897
	this.nullBit2 &= ~mask;
1898
	this.nullBit2 |= (otherInfo.nullBit2 & mask);
1899
	this.nullBit3 &= ~mask;
1900
	this.nullBit3 |= (otherInfo.nullBit3 & mask);
1901
	this.nullBit4 &= ~mask;
1902
	this.nullBit4 |= (otherInfo.nullBit4 & mask);
1903
	if (this.extra != null) {
1904
		// TODO(SH): implement
1905
		Assert.isTrue(false, "This analysis is not yet implemented for more than 64 variables"); //$NON-NLS-1$
1906
	}
1907
}
1893
public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() {
1908
public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() {
1894
	if (this == DEAD_END) {
1909
	if (this == DEAD_END) {
1895
		return this;
1910
		return this;
(-)compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java (+21 lines)
Lines 136-141 Link Here
136
	public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts";  //$NON-NLS-1$
136
	public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts";  //$NON-NLS-1$
137
	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
137
	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$
138
	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
139
	public static final String OPTION_ReportUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.unclosedCloseable"; //$NON-NLS-1$
140
	public static final String OPTION_ReportPotentiallyUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
141
	public static final String OPTION_ReportExplicitlyClosedAutoCloseable = "org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
139
	/**
142
	/**
140
	 * Possible values for configurable options
143
	 * Possible values for configurable options
141
	 */
144
	 */
Lines 238-243 Link Here
238
	public static final int UnusedObjectAllocation = IrritantSet.GROUP2 | ASTNode.Bit4;
241
	public static final int UnusedObjectAllocation = IrritantSet.GROUP2 | ASTNode.Bit4;
239
	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
242
	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
240
	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
243
	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
244
	public static final int UnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit7;
245
	public static final int PotentiallyUnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit8;
246
	public static final int ExplicitlyClosedAutoCloseable = IrritantSet.GROUP2 | ASTNode.Bit9;
241
247
242
	// Severity level for handlers
248
	// Severity level for handlers
243
	/** 
249
	/** 
Lines 547-552 Link Here
547
				return OPTION_ReportMethodCanBeStatic;
553
				return OPTION_ReportMethodCanBeStatic;
548
			case MethodCanBePotentiallyStatic :
554
			case MethodCanBePotentiallyStatic :
549
				return OPTION_ReportMethodCanBePotentiallyStatic;
555
				return OPTION_ReportMethodCanBePotentiallyStatic;
556
			case UnclosedCloseable :
557
				return OPTION_ReportUnclosedCloseable;
558
			case PotentiallyUnclosedCloseable :
559
				return OPTION_ReportPotentiallyUnclosedCloseable;
560
			case ExplicitlyClosedAutoCloseable :
561
				return OPTION_ReportExplicitlyClosedAutoCloseable;
550
		}
562
		}
551
		return null;
563
		return null;
552
	}
564
	}
Lines 709-714 Link Here
709
			OPTION_ReportUnusedTypeArgumentsForMethodInvocation,
721
			OPTION_ReportUnusedTypeArgumentsForMethodInvocation,
710
			OPTION_ReportUnusedWarningToken,
722
			OPTION_ReportUnusedWarningToken,
711
			OPTION_ReportVarargsArgumentNeedCast,
723
			OPTION_ReportVarargsArgumentNeedCast,
724
			OPTION_ReportUnclosedCloseable,
725
			OPTION_ReportPotentiallyUnclosedCloseable,
726
			OPTION_ReportExplicitlyClosedAutoCloseable,
712
		};
727
		};
713
		return result;
728
		return result;
714
	}
729
	}
Lines 973-978 Link Here
973
		optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
988
		optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
974
		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
989
		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
975
		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
990
		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
991
		optionsMap.put(OPTION_ReportUnclosedCloseable, getSeverityString(UnclosedCloseable));
992
		optionsMap.put(OPTION_ReportPotentiallyUnclosedCloseable, getSeverityString(PotentiallyUnclosedCloseable));
993
		optionsMap.put(OPTION_ReportExplicitlyClosedAutoCloseable, getSeverityString(ExplicitlyClosedAutoCloseable));
976
		return optionsMap;
994
		return optionsMap;
977
	}
995
	}
978
996
Lines 1402-1407 Link Here
1402
		if ((optionValue = optionsMap.get(OPTION_ReportUnusedObjectAllocation)) != null) updateSeverity(UnusedObjectAllocation, optionValue);
1420
		if ((optionValue = optionsMap.get(OPTION_ReportUnusedObjectAllocation)) != null) updateSeverity(UnusedObjectAllocation, optionValue);
1403
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
1421
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
1404
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
1422
		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
1423
		if ((optionValue = optionsMap.get(OPTION_ReportUnclosedCloseable)) != null) updateSeverity(UnclosedCloseable, optionValue);
1424
		if ((optionValue = optionsMap.get(OPTION_ReportPotentiallyUnclosedCloseable)) != null) updateSeverity(PotentiallyUnclosedCloseable, optionValue);
1425
		if ((optionValue = optionsMap.get(OPTION_ReportExplicitlyClosedAutoCloseable)) != null) updateSeverity(ExplicitlyClosedAutoCloseable, optionValue);
1405
1426
1406
		// Javadoc options
1427
		// Javadoc options
1407
		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
1428
		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
(-)compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java (-1 / +2 lines)
Lines 99-105 Link Here
99
			// group-2 warnings enabled by default
99
			// group-2 warnings enabled by default
100
			.set(
100
			.set(
101
				CompilerOptions.DeadCode
101
				CompilerOptions.DeadCode
102
				|CompilerOptions.Tasks);
102
				|CompilerOptions.Tasks
103
				|CompilerOptions.UnclosedCloseable);
103
			
104
			
104
		ALL.setAll();
105
		ALL.setAll();
105
		HIDING
106
		HIDING
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java (-2 / +18 lines)
Lines 971-976 Link Here
971
	variable.resolve();
971
	variable.resolve();
972
	return variable;
972
	return variable;
973
}
973
}
974
public boolean hasTypeBit(int bit) {
975
	// ensure hierarchy is resolved
976
	superclass();
977
	superInterfaces();
978
	return (this.typeBits & bit) != 0;
979
}
974
private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) {
980
private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) {
975
	// ParameterSignature = Identifier ':' TypeSignature
981
	// ParameterSignature = Identifier ':' TypeSignature
976
	//   or Identifier ':' TypeSignature(optional) InterfaceBound(s)
982
	//   or Identifier ':' TypeSignature(optional) InterfaceBound(s)
Lines 1139-1146 Link Here
1139
	// finish resolving the type
1145
	// finish resolving the type
1140
	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */);
1146
	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */);
1141
	this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
1147
	this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
1142
	if (this.superclass.problemId() == ProblemReasons.NotFound)
1148
	if (this.superclass.problemId() == ProblemReasons.NotFound) {
1143
		this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1149
		this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1150
	} else {
1151
		this.superclass.superclass();
1152
		this.superclass.superInterfaces();
1153
	}
1154
	this.typeBits |= this.superclass.typeBits;
1144
	return this.superclass;
1155
	return this.superclass;
1145
}
1156
}
1146
// NOTE: superInterfaces of binary types are resolved when needed
1157
// NOTE: superInterfaces of binary types are resolved when needed
Lines 1150-1157 Link Here
1150
1161
1151
	for (int i = this.superInterfaces.length; --i >= 0;) {
1162
	for (int i = this.superInterfaces.length; --i >= 0;) {
1152
		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */);
1163
		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */);
1153
		if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound)
1164
		if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) {
1154
			this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1165
			this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1166
		} else {
1167
			this.superInterfaces[i].superclass();
1168
			this.superInterfaces[i].superInterfaces();
1169
		}
1170
		this.typeBits |= this.superInterfaces[i].typeBits;
1155
	}
1171
	}
1156
	this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
1172
	this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
1157
	return this.superInterfaces;
1173
	return this.superInterfaces;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (+52 lines)
Lines 10-19 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.lookup;
11
package org.eclipse.jdt.internal.compiler.lookup;
12
12
13
import java.util.ArrayList;
14
import java.util.List;
15
13
import org.eclipse.jdt.core.compiler.CharOperation;
16
import org.eclipse.jdt.core.compiler.CharOperation;
14
import org.eclipse.jdt.internal.compiler.ast.*;
17
import org.eclipse.jdt.internal.compiler.ast.*;
15
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
18
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
19
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20
import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
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;
968
public int registerTrackingVariable(FakedTrackingVariable fakedTrackingVariable) {
969
	if (this.trackingVariables == null)
970
		this.trackingVariables = new ArrayList();
971
	this.trackingVariables.add(fakedTrackingVariable);
972
	MethodScope outerMethodScope = outerMostMethodScope();
973
	return outerMethodScope.analysisIndex + (++outerMethodScope.trackVarCount);
974
	
975
}
976
public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location) {
977
	if (this.trackingVariables == null) return;
978
	for (int i=0; i<this.trackingVariables.size(); i++) {
979
		FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
980
		if (trackingVar.hasReportedProblem)
981
			continue;
982
		int status = ExceptionHandlingFlowContext.getMaxUnsafeNullStatus(trackingVar.binding, flowInfo, flowContext);
983
		if (status == FlowInfo.NULL) {
984
			if (trackingVar.closedInNestedMethod)
985
				problemReporter().potentiallyUnclosedCloseable(trackingVar, location);
986
			else
987
				problemReporter().unclosedCloseable(trackingVar, location);
988
		} else if (status != FlowInfo.NON_NULL) {
989
			problemReporter().potentiallyUnclosedCloseable(trackingVar, location);
990
		} else { // status == FlowInfo.NON_NULL
991
			if (environment().globalOptions.complianceLevel >= ClassFileConstants.JDK1_7 
992
					&& !trackingVar.isInsideTryWithResources)
993
				problemReporter().explicitlyClosedAutoCloseable(trackingVar);
994
		}
995
	}
996
}
997
/**
998
 * Answer a mask identifying all tracking variables in scope.
999
 * @return a bitset of variable ids
1000
 */
1001
public long getTrackVarsMask() {
1002
	if (this.trackingVariables == null) return 0;
1003
	long mask = 0;
1004
	for (int i=0; i<this.trackingVariables.size(); i++) {
1005
		FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
1006
		mask |= (1 << trackingVar.binding.id);
1007
	}
1008
	if (this.parent instanceof BlockScope)
1009
		mask |= ((BlockScope) this.parent).getTrackVarsMask();
1010
	return mask;
1011
}
960
}
1012
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java (+2 lines)
Lines 907-912 Link Here
907
			} else {
907
			} else {
908
				// only want to reach here when no errors are reported
908
				// only want to reach here when no errors are reported
909
				sourceType.superclass = superclass;
909
				sourceType.superclass = superclass;
910
				sourceType.typeBits |= superclass.typeBits;
910
				return true;
911
				return true;
911
			}
912
			}
912
		}
913
		}
Lines 1017-1022 Link Here
1017
				noProblems &= superInterfaceRef.resolvedType.isValidBinding();
1018
				noProblems &= superInterfaceRef.resolvedType.isValidBinding();
1018
			}
1019
			}
1019
			// only want to reach here when no errors are reported
1020
			// only want to reach here when no errors are reported
1021
			sourceType.typeBits |= superInterface.typeBits;
1020
			interfaceBindings[count++] = superInterface;
1022
			interfaceBindings[count++] = superInterface;
1021
		}
1023
		}
1022
		// hold onto all correctly resolved superinterfaces
1024
		// hold onto all correctly resolved superinterfaces
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java (+3 lines)
Lines 19-24 Link Here
19
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
19
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
20
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
20
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
21
import org.eclipse.jdt.internal.compiler.ast.Annotation;
21
import org.eclipse.jdt.internal.compiler.ast.Annotation;
22
import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
22
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
23
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
23
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
24
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
24
import org.eclipse.jdt.internal.compiler.impl.Constant;
25
import org.eclipse.jdt.internal.compiler.impl.Constant;
Lines 39-44 Link Here
39
	public int[] initializationPCs;
40
	public int[] initializationPCs;
40
	public int initializationCount = 0;
41
	public int initializationCount = 0;
41
42
43
	public FakedTrackingVariable closeTracker; // track closing of instances of type AutoCloseable
44
42
	// for synthetic local variables
45
	// for synthetic local variables
43
	// if declaration slot is not positionned, the variable will not be listed in attribute
46
	// if declaration slot is not positionned, the variable will not be listed in attribute
44
	// 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)
47
	// 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 (+3 lines)
Lines 49-54 Link Here
49
	// inner-emulation
49
	// inner-emulation
50
	public SyntheticArgumentBinding[] extraSyntheticArguments;
50
	public SyntheticArgumentBinding[] extraSyntheticArguments;
51
51
52
	// count number of tracking variables, see FakedTrackingVariable
53
	int trackVarCount;
54
52
public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) {
55
public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) {
53
	super(METHOD_SCOPE, parent);
56
	super(METHOD_SCOPE, parent);
54
	this.locals = new LocalVariableBinding[5];
57
	this.locals = new LocalVariableBinding[5];
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java (+7 lines)
Lines 629-634 Link Here
629
	    return this.type.hasMemberTypes();
629
	    return this.type.hasMemberTypes();
630
	}
630
	}
631
631
632
	public boolean hasTypeBit(int bit) {
633
		TypeBinding erasure = erasure();
634
		if (erasure instanceof ReferenceBinding)
635
			return ((ReferenceBinding) erasure).hasTypeBit(bit);
636
		return false;
637
	}
638
632
	/**
639
	/**
633
	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding)
640
	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding)
634
	 */
641
	 */
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java (+6 lines)
Lines 40-45 Link Here
40
	return this.closestMatch;
40
	return this.closestMatch;
41
}
41
}
42
42
43
public boolean hasTypeBit(int bit) {
44
	if (this.closestMatch != null)
45
		return this.closestMatch.hasTypeBit(bit);
46
	return false;
47
}
48
43
/* API
49
/* API
44
* Answer the problem id associated with the receiver.
50
* Answer the problem id associated with the receiver.
45
* NoError if the receiver is a valid binding.
51
* NoError if the receiver is a valid binding.
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java (-1 / +12 lines)
Lines 17-22 Link Here
17
import java.util.Arrays;
17
import java.util.Arrays;
18
import java.util.Comparator;
18
import java.util.Comparator;
19
19
20
import org.eclipse.core.runtime.Assert;
20
import org.eclipse.jdt.core.compiler.CharOperation;
21
import org.eclipse.jdt.core.compiler.CharOperation;
21
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
22
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
22
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
23
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
Lines 45-50 Link Here
45
46
46
	private SimpleLookupTable compatibleCache;
47
	private SimpleLookupTable compatibleCache;
47
48
49
	int typeBits;
50
48
	public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */};
51
	public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */};
49
52
50
	private static final Comparator FIELD_COMPARATOR = new Comparator() {
53
	private static final Comparator FIELD_COMPARATOR = new Comparator() {
Lines 428-435 Link Here
428
				case 'A' :
431
				case 'A' :
429
					switch(typeName.length) {
432
					switch(typeName.length) {
430
						case 13 :
433
						case 13 :
431
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2]))
434
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
432
								this.id = TypeIds.T_JavaLangAutoCloseable;
435
								this.id = TypeIds.T_JavaLangAutoCloseable;
436
								this.typeBits |= TypeIds.BitAutoCloseable; 
437
							}
433
							return;
438
							return;
434
						case 14:
439
						case 14:
435
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
440
							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
Lines 928-933 Link Here
928
	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
933
	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
929
}
934
}
930
935
936
public boolean hasTypeBit(int bit) {
937
	// overridden in relevant subclasses
938
	Assert.isTrue(false, "Unsupported query for type "+getClass().getName()); //$NON-NLS-1$
939
	return false; // never reached
940
}
941
931
/** Answer true if the receiver implements anInterface or is identical to anInterface.
942
/** Answer true if the receiver implements anInterface or is identical to anInterface.
932
* If searchHierarchy is true, then also search the receiver's superclasses.
943
* If searchHierarchy is true, then also search the receiver's superclasses.
933
*
944
*
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java (+8 lines)
Lines 18-23 Link Here
18
import java.util.HashMap;
18
import java.util.HashMap;
19
import java.util.Iterator;
19
import java.util.Iterator;
20
20
21
import org.eclipse.core.runtime.Assert;
21
import org.eclipse.jdt.core.compiler.CharOperation;
22
import org.eclipse.jdt.core.compiler.CharOperation;
22
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
23
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
23
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
24
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
Lines 1066-1071 Link Here
1066
	return accessors[1];
1067
	return accessors[1];
1067
}
1068
}
1068
1069
1070
public boolean hasTypeBit(int bit) {
1071
	// source types initialize type bits during connectSuperclass/interfaces()
1072
	if (!isLocalType())
1073
		Assert.isTrue((this.tagBits & TagBits.EndHierarchyCheck) != 0, "Hierarchy should be connected"); //$NON-NLS-1$
1074
	return (this.typeBits & bit) != 0;
1075
}
1076
1069
/**
1077
/**
1070
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
1078
 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
1071
 */
1079
 */
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java (+1 lines)
Lines 154-159 Link Here
154
			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
154
			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
155
	};
155
	};
156
	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
156
	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
157
	char[] CLOSE = "close".toCharArray(); //$NON-NLS-1$
157
158
158
	// Constraints for generic type argument inference
159
	// Constraints for generic type argument inference
159
	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
160
	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java (+2 lines)
Lines 173-176 Link Here
173
	final int Object2Object = T_JavaLangObject + (T_JavaLangObject << 4);
173
	final int Object2Object = T_JavaLangObject + (T_JavaLangObject << 4);
174
	final int BOXING = 0x200;
174
	final int BOXING = 0x200;
175
	final int UNBOXING = 0x400;
175
	final int UNBOXING = 0x400;
176
177
	final int BitAutoCloseable = 1;
176
}
178
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java (+14 lines)
Lines 42-47 Link Here
42
		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
42
		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
43
		this.tagBits |= TagBits.HasTypeVariable;
43
		this.tagBits |= TagBits.HasTypeVariable;
44
		this.environment = environment;
44
		this.environment = environment;
45
		this.typeBits = -1;
45
	}
46
	}
46
47
47
	/**
48
	/**
Lines 307-312 Link Here
307
		return true;
308
		return true;
308
	}
309
	}
309
310
311
	public boolean hasTypeBit(int bit) {
312
		if (this.typeBits == -1) {
313
			// initialize from bounds
314
			this.typeBits = 0;
315
			if (this.superclass != null)
316
				this.typeBits |= this.superclass.typeBits;
317
			if (this.superInterfaces != null)
318
				for (int i = 0, l = this.superInterfaces.length; i < l; i++)
319
					this.typeBits |= this.superInterfaces[i].typeBits;
320
		}
321
		return (this.typeBits & bit) != 0;
322
	}
323
310
	/**
324
	/**
311
	 * Returns true if the type variable is directly bound to a given type
325
	 * Returns true if the type variable is directly bound to a given type
312
	 */
326
	 */
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java (+14 lines)
Lines 54-59 Link Here
54
		if (bound instanceof UnresolvedReferenceBinding)
54
		if (bound instanceof UnresolvedReferenceBinding)
55
			((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
55
			((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
56
		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
56
		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
57
		this.typeBits = -1;
57
	}
58
	}
58
59
59
	public int kind() {
60
	public int kind() {
Lines 420-425 Link Here
420
		return this.genericType.hashCode();
421
		return this.genericType.hashCode();
421
	}
422
	}
422
423
424
	public boolean hasTypeBit(int bit) {
425
		if (this.typeBits == -1) {
426
			// initialize from upper bounds
427
			this.typeBits = 0;
428
			if (this.superclass != null)
429
				this.typeBits |= this.superclass.typeBits;
430
			if (this.superInterfaces != null)
431
				for (int i = 0, l = this.superInterfaces.length; i < l; i++)
432
					this.typeBits |= this.superInterfaces[i].typeBits;
433
		}
434
		return (this.typeBits & bit) != 0;
435
	}
436
423
	void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
437
	void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
424
		this.genericType = someGenericType;
438
		this.genericType = someGenericType;
425
		this.bound = someBound;
439
		this.bound = someBound;
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (+60 lines)
Lines 55-60 Link Here
55
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
55
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
56
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
56
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
57
import org.eclipse.jdt.internal.compiler.ast.Expression;
57
import org.eclipse.jdt.internal.compiler.ast.Expression;
58
import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
58
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
59
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
59
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
60
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
60
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
61
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
Lines 430-435 Link Here
430
			
431
			
431
		case IProblem.MethodCanBePotentiallyStatic:
432
		case IProblem.MethodCanBePotentiallyStatic:
432
			return CompilerOptions.MethodCanBePotentiallyStatic;
433
			return CompilerOptions.MethodCanBePotentiallyStatic;
434
			
435
		case IProblem.UnclosedCloseable:
436
		case IProblem.UnclosedCloseableAtExit:
437
			return CompilerOptions.UnclosedCloseable;
438
		case IProblem.PotentiallyUnclosedCloseable:
439
		case IProblem.PotentiallyUnclosedCloseableAtExit:
440
			return CompilerOptions.PotentiallyUnclosedCloseable;
441
		case IProblem.ExplicitlyClosedAutoCloseable:
442
			return CompilerOptions.ExplicitlyClosedAutoCloseable;
433
	}
443
	}
434
	return 0;
444
	return 0;
435
}
445
}
Lines 462-467 Link Here
462
			case CompilerOptions.ParameterAssignment :
472
			case CompilerOptions.ParameterAssignment :
463
			case CompilerOptions.MethodCanBeStatic :
473
			case CompilerOptions.MethodCanBeStatic :
464
			case CompilerOptions.MethodCanBePotentiallyStatic :
474
			case CompilerOptions.MethodCanBePotentiallyStatic :
475
			case CompilerOptions.ExplicitlyClosedAutoCloseable :
465
				return CategorizedProblem.CAT_CODE_STYLE;
476
				return CategorizedProblem.CAT_CODE_STYLE;
466
477
467
			case CompilerOptions.MaskedCatchBlock :
478
			case CompilerOptions.MaskedCatchBlock :
Lines 483-488 Link Here
483
			case CompilerOptions.ShouldImplementHashcode :
494
			case CompilerOptions.ShouldImplementHashcode :
484
			case CompilerOptions.DeadCode :
495
			case CompilerOptions.DeadCode :
485
			case CompilerOptions.UnusedObjectAllocation :
496
			case CompilerOptions.UnusedObjectAllocation :
497
			case CompilerOptions.UnclosedCloseable :
498
			case CompilerOptions.PotentiallyUnclosedCloseable :
486
				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
499
				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
487
			
500
			
488
			case CompilerOptions.OverriddenPackageDefaultMethod :
501
			case CompilerOptions.OverriddenPackageDefaultMethod :
Lines 7884-7887 Link Here
7884
			type.sourceStart, 
7897
			type.sourceStart, 
7885
			type.sourceEnd);
7898
			type.sourceEnd);
7886
}
7899
}
7900
public void potentiallyUnclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
7901
	if (location == null) {
7902
		this.handle(
7903
			IProblem.PotentiallyUnclosedCloseable,
7904
			NoArgument,
7905
			NoArgument,
7906
			trackVar.sourceStart,
7907
			trackVar.sourceEnd);
7908
	} else {
7909
		String[] args = { String.valueOf(trackVar.name) };
7910
		this.handle(
7911
			IProblem.PotentiallyUnclosedCloseableAtExit,
7912
			args,
7913
			args,
7914
			location.sourceStart,
7915
			location.sourceEnd);
7916
	}
7917
	trackVar.hasReportedProblem = true;
7918
}
7919
public void unclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
7920
	if (location == null) {
7921
		this.handle(
7922
			IProblem.UnclosedCloseable,
7923
			NoArgument,
7924
			NoArgument,
7925
			trackVar.sourceStart,
7926
			trackVar.sourceEnd);
7927
	} else {
7928
		String[] args = { String.valueOf(trackVar.name) };
7929
		this.handle(
7930
			IProblem.UnclosedCloseableAtExit,
7931
			args,
7932
			args,
7933
			location.sourceStart,
7934
			location.sourceEnd);
7935
	}
7936
	trackVar.hasReportedProblem = true;
7937
}
7938
public void explicitlyClosedAutoCloseable(FakedTrackingVariable trackVar) {
7939
	String[] args = { String.valueOf(trackVar.name) };
7940
	this.handle(
7941
		IProblem.ExplicitlyClosedAutoCloseable,
7942
		args,
7943
		args,
7944
		trackVar.sourceStart,
7945
		trackVar.sourceEnd);	
7946
}
7887
}
7947
}
(-)compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties (+5 lines)
Lines 646-651 Link Here
646
881 = Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum constants are permitted
646
881 = Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum constants are permitted
647
882 = Unhandled exception type {0} thrown by automatic close() invocation on {1}
647
882 = Unhandled exception type {0} thrown by automatic close() invocation on {1}
648
883 = '<>' operator is not allowed for source level below 1.7
648
883 = '<>' operator is not allowed for source level below 1.7
649
884 = Value of type AutoCloseable is not closed on all paths.
650
885 = Instance '{0}' of type AutoCloseable may be unclosed at this point.
651
886 = Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.
652
887 = Instance '{0}' of type AutoCloseable is not closed at this point.
653
888 = Instance '{0}' should be managed by try-with-resource.
649
654
650
### ELABORATIONS
655
### ELABORATIONS
651
## Access restrictions
656
## Access restrictions
(-)model/org/eclipse/jdt/core/JavaCore.java (+46 lines)
Lines 1357-1362 Link Here
1357
	 */
1357
	 */
1358
	public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
1358
	public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
1359
	/**
1359
	/**
1360
	 * Compiler option ID: Reporting a resource that is not closed properly.
1361
	 * <p>When enabled, that compiler will issue an error or a warning if a local variable 
1362
	 * 	  holds a value of type AutoCloseable (or Closeable if compliance is &lt; 1.7)
1363
	 *    and if flow analysis shows that the method <code>close()</code> is not invoked locally on that value.
1364
	 * <dl>
1365
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code></dd>
1366
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1367
	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
1368
	 * </dl>
1369
	 * @since 3.7
1370
	 * @category CompilerOptionID
1371
	 */
1372
	public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$
1373
	/**
1374
	 * Compiler option ID: Reporting a resource that may not be closed properly.
1375
	 * <p>When enabled, that compiler will issue an error or a warning if a local variable 
1376
	 * 	  holds a value of type AutoCloseable (or Closeable if compliance is &lt; 1.7)
1377
	 *    and if flow analysis shows that the method <code>close()</code> is not invoked locally 
1378
	 *    on that value for all execution paths.
1379
	 * <dl>
1380
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
1381
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1382
	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
1383
	 * </dl>
1384
	 * @since 3.7
1385
	 * @category CompilerOptionID
1386
	 */
1387
	public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
1388
	/**
1389
	 * Compiler option ID: Reporting a resource that is not managed by try-with-resources.
1390
	 * <p>When enabled, that compiler will issue an error or a warning if a local variable 
1391
	 * 	  holds a value of type AutoCloseable, and if the method <code>close()</code> is
1392
	 * 	  explicitly invoked on that resource, but the resource is not managed by a
1393
	 * 	  try-with-resources block.
1394
	 * <p>Note that this option is not surfaced in the UI, as it is intended only for internal 
1395
	 * 	  use for computing quick assists / cleanups. 
1396
	 * <dl>
1397
	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
1398
	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
1399
	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
1400
	 * </dl>
1401
	 * @since 3.7
1402
	 * @category CompilerOptionID
1403
	 */
1404
	public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
1405
	/**
1360
	 * Compiler option ID: Setting Source Compatibility Mode.
1406
	 * 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
1407
	 * <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
1408
	 *    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 lines)
Lines 1816-1821 Link Here
1816
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + 
1816
			"		<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" + 
1817
			"		<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" + 
1818
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + 
1819
			"		<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" + 
1820
			"		<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" + 
1821
			"		<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" + 
1822
			"		<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" + 
1858
			"		<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" + 
1859
			"		<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" + 
1860
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + 
1861
			"		<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" + 
1862
			"		<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" + 
1863
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + 
1862
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface\" value=\"ignore\"/>\n" + 
1864
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface\" value=\"ignore\"/>\n" + 
Lines 1871-1876 Link Here
1871
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + 
1873
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + 
1872
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" +
1874
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" +
1873
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + 
1875
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + 
1876
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" + 
1874
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + 
1877
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + 
1875
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + 
1878
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + 
1876
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + 
1879
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + 
(-)src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java (+10 lines)
Lines 444-449 Link Here
444
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED);
444
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED);
445
		expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED);
445
		expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED);
446
		expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED);
446
		expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED);
447
		expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
447
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
448
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
448
		expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
449
		expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
449
		expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
450
		expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
Lines 768-773 Link Here
768
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
769
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
769
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
770
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
770
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
771
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
772
		expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
773
		expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
771
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
774
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
772
		expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
775
		expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
773
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
776
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
Lines 830-835 Link Here
830
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
833
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
831
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT));
834
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT));
832
		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));
833
		expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
838
		expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
834
		expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
839
		expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
835
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
840
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
Lines 1110-1115 Link Here
1110
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP);
1115
		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP);
1111
		expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP);
1116
		expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP);
1112
		expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP);
1117
		expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP);
1118
		expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE));
1113
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP);
1119
		expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP);
1114
		expectedProblemAttributes.put("ExternalProblemFixable", SKIP);
1120
		expectedProblemAttributes.put("ExternalProblemFixable", SKIP);
1115
		expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP);
1121
		expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP);
Lines 1434-1439 Link Here
1434
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP);
1440
		expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP);
1435
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
1441
		expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT));
1436
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
1442
		expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
1443
		expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
1444
		expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
1437
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
1445
		expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE));
1438
		expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
1446
		expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP);
1439
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
1447
		expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP);
Lines 1496-1501 Link Here
1496
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION));
1504
		expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION));
1497
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING));
1505
		expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING));
1498
		expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING));
1506
		expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING));
1507
		expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE));
1508
		expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE));
1499
		expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP);
1509
		expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP);
1500
		expectedProblemAttributes.put("UndefinedConstructor", SKIP);
1510
		expectedProblemAttributes.put("UndefinedConstructor", SKIP);
1501
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP);
1511
		expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP);
(-)src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java (-5 / +462 lines)
Lines 16-28 Link Here
16
16
17
import java.util.Map;
17
import java.util.Map;
18
18
19
import org.eclipse.jdt.core.JavaCore;
19
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
20
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
20
21
21
import junit.framework.Test;
22
import junit.framework.Test;
22
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
23
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
23
24
24
static {
25
static {
25
//	TESTS_NAMES = new String[] { "test053" };
26
	TESTS_NAMES = new String[] { "test055" };
26
//	TESTS_NUMBERS = new int[] { 50 };
27
//	TESTS_NUMBERS = new int[] { 50 };
27
//	TESTS_RANGE = new int[] { 11, -1 };
28
//	TESTS_RANGE = new int[] { 11, -1 };
28
}
29
}
Lines 489-500 Link Here
489
		"	               ^^\n" + 
490
		"	               ^^\n" + 
490
		"Dead code\n" + 
491
		"Dead code\n" + 
491
		"----------\n" + 
492
		"----------\n" + 
492
		"3. ERROR in X.java (at line 5)\n" + 
493
		"3. WARNING in X.java (at line 5)\n" + 
494
		"	Y why = new Y();\n" + 
495
		"	  ^^^\n" + 
496
		"Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.\n" + 
497
		"----------\n" + 
498
		"4. ERROR in X.java (at line 5)\n" + 
493
		"	Y why = new Y();\n" + 
499
		"	Y why = new Y();\n" + 
494
		"	        ^^^^^^^\n" + 
500
		"	        ^^^^^^^\n" + 
495
		"Unhandled exception type WeirdException\n" + 
501
		"Unhandled exception type WeirdException\n" + 
496
		"----------\n" + 
502
		"----------\n" + 
497
		"4. WARNING in X.java (at line 22)\n" + 
503
		"5. WARNING in X.java (at line 22)\n" + 
498
		"	class WeirdException extends Throwable {}\n" + 
504
		"	class WeirdException extends Throwable {}\n" + 
499
		"	      ^^^^^^^^^^^^^^\n" + 
505
		"	      ^^^^^^^^^^^^^^\n" + 
500
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
506
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
Lines 562-573 Link Here
562
		"	               ^^\n" + 
568
		"	               ^^\n" + 
563
		"Dead code\n" + 
569
		"Dead code\n" + 
564
		"----------\n" + 
570
		"----------\n" + 
565
		"3. ERROR in X.java (at line 5)\n" + 
571
		"3. WARNING in X.java (at line 5)\n" + 
572
		"	Y why = new Y();\n" + 
573
		"	  ^^^\n" + 
574
		"Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.\n" + 
575
		"----------\n" + 
576
		"4. ERROR in X.java (at line 5)\n" + 
566
		"	Y why = new Y();\n" + 
577
		"	Y why = new Y();\n" + 
567
		"	        ^^^^^^^\n" + 
578
		"	        ^^^^^^^\n" + 
568
		"Unhandled exception type WeirdException\n" + 
579
		"Unhandled exception type WeirdException\n" + 
569
		"----------\n" + 
580
		"----------\n" + 
570
		"4. WARNING in X.java (at line 20)\n" + 
581
		"5. WARNING in X.java (at line 20)\n" + 
571
		"	class WeirdException extends Throwable {}\n" + 
582
		"	class WeirdException extends Throwable {}\n" + 
572
		"	      ^^^^^^^^^^^^^^\n" + 
583
		"	      ^^^^^^^^^^^^^^\n" + 
573
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
584
		"The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + 
Lines 3341-3346 Link Here
3341
		"Object.Integer cannot be resolved to a type\n" + 
3352
		"Object.Integer cannot be resolved to a type\n" + 
3342
		"----------\n");
3353
		"----------\n");
3343
}
3354
}
3355
// Bug 349326 - [1.7] new warning for missing try-with-resources
3356
// a method uses an AutoCloseable without ever closing it.
3357
public void test055() {
3358
	Map options = getCompilerOptions();
3359
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3360
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3361
	this.runNegativeTest(
3362
		new String[] {
3363
			"X.java",
3364
			"import java.io.File;\n" +
3365
			"import java.io.FileReader;\n" +
3366
			"import java.io.IOException;\n" +
3367
			"public class X {\n" +
3368
			"    void foo() throws IOException {\n" +
3369
			"        File file = new File(\"somefile\");\n" +
3370
			"        FileReader fileReader = new FileReader(file);\n" +
3371
// not invoking any methods on FileReader, try to avoid necessary call to superclass()
3372
//			"        char[] in = new char[50];\n" +
3373
//			"        fileReader.read(in);\n" +
3374
			"    }\n" +
3375
			"    public static void main(String[] args) throws IOException {\n" +
3376
			"        new X().foo();\n" +
3377
			"    }\n" +
3378
			"}\n"
3379
		},
3380
		"----------\n" + 
3381
		"1. ERROR in X.java (at line 7)\n" + 
3382
		"	FileReader fileReader = new FileReader(file);\n" + 
3383
		"	           ^^^^^^^^^^\n" + 
3384
		"Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.\n" + 
3385
		"----------\n",
3386
		null,
3387
		true,
3388
		options);
3389
}
3390
// Bug 349326 - [1.7] new warning for missing try-with-resources
3391
// a method uses an AutoCloseable and closes it but exception may occur earlier.
3392
public void test055a() {
3393
	Map options = getCompilerOptions();
3394
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3395
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3396
	this.runNegativeTest(
3397
		new String[] {
3398
			"X.java",
3399
			"import java.io.File;\n" +
3400
			"import java.io.FileReader;\n" +
3401
			"import java.io.IOException;\n" +
3402
			"public class X {\n" +
3403
			"    void foo() throws IOException {\n" +
3404
			"        File file = new File(\"somefile\");\n" +
3405
			"        FileReader fileReader = new FileReader(file);\n" +
3406
			"        char[] in = new char[50];\n" +
3407
			"        fileReader.read(in);\n" +
3408
			"		 fileReader.close();\n" +
3409
			"    }\n" +
3410
			"    public static void main(String[] args) {\n" +
3411
			"        try {\n" +
3412
			"            new X().foo();\n" +
3413
			"        } catch (IOException ioex) {\n" +
3414
			"            System.out.println(\"caught\");\n" +
3415
			"        }\n" +
3416
			"    }\n" +
3417
			"}\n"
3418
		},
3419
		"----------\n" + 
3420
		"1. ERROR in X.java (at line 7)\n" + 
3421
		"	FileReader fileReader = new FileReader(file);\n" + 
3422
		"	           ^^^^^^^^^^\n" + 
3423
		"Value of type AutoCloseable is not closed on all paths.\n" + 
3424
		"----------\n",
3425
		null,
3426
		true,
3427
		options);
3428
}
3429
// Bug 349326 - [1.7] new warning for missing try-with-resources
3430
// a method uses an AutoCloseable and closes it properly in a finally block
3431
public void test055b() {
3432
	Map options = getCompilerOptions();
3433
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3434
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3435
	this.runConformTest(
3436
		new String[] {
3437
			"X.java",
3438
			"import java.io.File;\n" +
3439
			"import java.io.FileReader;\n" +
3440
			"import java.io.IOException;\n" +
3441
			"public class X {\n" +
3442
			"    void foo() throws IOException {\n" +
3443
			"        File file = new File(\"somefile\");\n" +
3444
			"        FileReader fileReader = new FileReader(file);\n" +
3445
			"        try {\n" +
3446
			"            char[] in = new char[50];\n" +
3447
			"            fileReader.read(in);\n" +
3448
			"        } finally {\n" +
3449
			"		     fileReader.close();\n" +
3450
			"        }\n" +
3451
			"    }\n" +
3452
			"    public static void main(String[] args) {\n" +
3453
			"        try {\n" +
3454
			"            new X().foo();\n" +
3455
			"        } catch (IOException ioex) {\n" +
3456
			"            System.out.println(\"caught\");\n" +
3457
			"        }\n" +
3458
			"    }\n" +
3459
			"}\n"
3460
		},
3461
		"caught", /*output*/
3462
		null/*classLibs*/,
3463
		true/*shouldFlush*/,
3464
		null/*vmargs*/,
3465
		options,
3466
		null/*requestor*/);
3467
}
3468
// Bug 349326 - [1.7] new warning for missing try-with-resources
3469
// a method uses an AutoCloseable properly within try-with-resources.
3470
public void test055c() {
3471
	Map options = getCompilerOptions();
3472
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3473
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3474
	this.runConformTest(
3475
		new String[] {
3476
			"X.java",
3477
			"import java.io.File;\n" +
3478
			"import java.io.FileReader;\n" +
3479
			"import java.io.IOException;\n" +
3480
			"public class X {\n" +
3481
			"    void foo() throws IOException {\n" +
3482
			"        File file = new File(\"somefile\");\n" +
3483
			"        try (FileReader fileReader = new FileReader(file)) {\n" +
3484
			"            char[] in = new char[50];\n" +
3485
			"            fileReader.read(in);\n" +
3486
			"		 }\n" +
3487
			"    }\n" +
3488
			"    public static void main(String[] args) {\n" +
3489
			"        try {\n" +
3490
			"            new X().foo();\n" +
3491
			"        } catch (IOException ioex) {\n" +
3492
			"            System.out.println(\"caught\");\n" +
3493
			"        }\n" +
3494
			"    }\n" +
3495
			"}\n"
3496
		},
3497
		"caught", /*output*/
3498
		null/*classLibs*/,
3499
		true/*shouldFlush*/,
3500
		null/*vmargs*/,
3501
		options,
3502
		null/*requestor*/);
3503
}
3504
// Bug 349326 - [1.7] new warning for missing try-with-resources
3505
// a method uses two AutoCloseables (testing independent analysis)
3506
// - one closeable may be unclosed at a conditional return
3507
// - the other is only conditionally closed
3508
public void test055d() {
3509
	Map options = getCompilerOptions();
3510
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3511
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3512
	this.runNegativeTest(
3513
		new String[] {
3514
			"X.java",
3515
			"import java.io.File;\n" +
3516
			"import java.io.FileReader;\n" +
3517
			"import java.io.IOException;\n" +
3518
			"public class X {\n" +
3519
			"    void foo(boolean flag1, boolean flag2) throws IOException {\n" +
3520
			"        File file = new File(\"somefile\");\n" +
3521
			"        char[] in = new char[50];\n" +
3522
			"        FileReader fileReader1 = new FileReader(file);\n" +
3523
			"        fileReader1.read(in);\n" +
3524
			"        FileReader fileReader2 = new FileReader(file);\n" +
3525
			"        fileReader2.read(in);\n" +
3526
			"        if (flag1) {\n" +
3527
			"            fileReader2.close();\n" +
3528
			"            return;\n" +
3529
			"        } else if (flag2) {\n" +
3530
			"            fileReader2.close();\n" +
3531
			"        }\n" +
3532
			"        fileReader1.close();\n" +
3533
			"    }\n" +
3534
			"    public static void main(String[] args) throws IOException {\n" +
3535
			"        new X().foo(false, true);\n" +
3536
			"    }\n" +
3537
			"}\n"
3538
		},
3539
		"----------\n" + 
3540
		"1. WARNING in X.java (at line 10)\n" + 
3541
		"	FileReader fileReader2 = new FileReader(file);\n" + 
3542
		"	           ^^^^^^^^^^^\n" + 
3543
		"Value of type AutoCloseable is not closed on all paths.\n" + 
3544
		"----------\n" + 
3545
		"2. ERROR in X.java (at line 14)\n" + 
3546
		"	return;\n" + 
3547
		"	^^^^^^^\n" + 
3548
		"Instance \'fileReader1\' of type AutoCloseable is not closed at this point.\n" + 
3549
		"----------\n",
3550
		null,
3551
		true,
3552
		options);
3553
}
3554
// Bug 349326 - [1.7] new warning for missing try-with-resources
3555
// one method returns an AutoCleasble, a second method uses this object without ever closing it.
3556
public void test055e() {
3557
	Map options = getCompilerOptions();
3558
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3559
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3560
	this.runNegativeTest(
3561
		new String[] {
3562
			"X.java",
3563
			"import java.io.File;\n" +
3564
			"import java.io.FileReader;\n" +
3565
			"import java.io.IOException;\n" +
3566
			"public class X {\n" +
3567
			"    FileReader getReader(String filename) throws IOException {\n" +
3568
			"        File file = new File(\"somefile\");\n" +
3569
			"        FileReader fileReader = new FileReader(file);\n" +
3570
			"        return fileReader;\n" + 		// don't complain here, pass responsibility to caller
3571
			"    }\n" +
3572
			"    void foo() throws IOException {\n" +
3573
			"        FileReader reader = getReader(\"somefile\");\n" +
3574
			"        char[] in = new char[50];\n" +
3575
			"        reader.read(in);\n" +
3576
			"    }\n" +
3577
			"    public static void main(String[] args) throws IOException {\n" +
3578
			"        new X().foo();\n" +
3579
			"    }\n" +
3580
			"}\n"
3581
		},
3582
		"----------\n" + 
3583
		"1. ERROR in X.java (at line 11)\n" + 
3584
		"	FileReader reader = getReader(\"somefile\");\n" + 
3585
		"	           ^^^^^^\n" + 
3586
		"Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.\n" + 
3587
		"----------\n",
3588
		null,
3589
		true,
3590
		options);
3591
}
3592
// Bug 349326 - [1.7] new warning for missing try-with-resources
3593
// a method explicitly closes its AutoCloseable rather than using t-w-r
3594
public void test055f() {
3595
	Map options = getCompilerOptions();
3596
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3597
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
3598
	options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
3599
	this.runNegativeTest(
3600
		new String[] {
3601
			"X.java",
3602
			"import java.io.File;\n" +
3603
			"import java.io.FileReader;\n" +
3604
			"import java.io.IOException;\n" +
3605
			"public class X {\n" +
3606
			"    void foo() throws IOException {\n" +
3607
			"        File file = new File(\"somefile\");\n" +
3608
			"        FileReader fileReader = null;\n" +
3609
			"        try {\n" +
3610
			"            fileReader = new FileReader(file);\n" +
3611
			"            char[] in = new char[50];\n" +
3612
			"            fileReader.read(in);\n" +
3613
			"        } finally {\n" +
3614
			"            fileReader.close();\n" +
3615
			"        }\n" +
3616
			"    }\n" +
3617
			"    public static void main(String[] args) throws IOException {\n" +
3618
			"        new X().foo();\n" +
3619
			"    }\n" +
3620
			"}\n"
3621
		},
3622
		"----------\n" + 
3623
		"1. ERROR in X.java (at line 7)\n" + 
3624
		"	FileReader fileReader = null;\n" + 
3625
		"	           ^^^^^^^^^^\n" + 
3626
		"Instance \'fileReader\' should be managed by try-with-resource.\n" + 
3627
		"----------\n",
3628
		null,
3629
		true,
3630
		options);
3631
}
3632
// Bug 349326 - [1.7] new warning for missing try-with-resources
3633
// an AutoCloseable local is re-assigned
3634
public void test055g() {
3635
	Map options = getCompilerOptions();
3636
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3637
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3638
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3639
	this.runNegativeTest(
3640
		new String[] {
3641
			"X.java",
3642
			"import java.io.File;\n" +
3643
			"import java.io.FileReader;\n" +
3644
			"import java.io.IOException;\n" +
3645
			"public class X {\n" +
3646
			"    void foo() throws IOException {\n" +
3647
			"        File file = new File(\"somefile\");\n" +
3648
			"        FileReader fileReader = new FileReader(file);\n" +
3649
			"        char[] in = new char[50];\n" +
3650
			"        fileReader.read(in);\n" +
3651
			"        fileReader = new FileReader(file);\n" +
3652
			"        fileReader.read(in);\n" +
3653
			"        fileReader.close();\n" +
3654
			"    }\n" +
3655
			"    public static void main(String[] args) throws IOException {\n" +
3656
			"        new X().foo();\n" +
3657
			"    }\n" +
3658
			"}\n"
3659
		},
3660
		"----------\n" + 
3661
		"1. ERROR in X.java (at line 10)\n" + 
3662
		"	fileReader = new FileReader(file);\n" + 
3663
		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
3664
		"Instance \'fileReader\' of type AutoCloseable is not closed at this point.\n" + 
3665
		"----------\n",
3666
		null,
3667
		true,
3668
		options);
3669
}
3670
// Bug 349326 - [1.7] new warning for missing try-with-resources
3671
// two AutoCloseables at different nesting levels (anonymous local type)
3672
public void test055h() {
3673
	Map options = getCompilerOptions();
3674
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3675
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3676
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3677
	this.runNegativeTest(
3678
		new String[] {
3679
			"X.java",
3680
			"import java.io.File;\n" +
3681
			"import java.io.FileReader;\n" +
3682
			"import java.io.IOException;\n" +
3683
			"public class X {\n" +
3684
			"    void foo() throws IOException {\n" +
3685
			"        final File file = new File(\"somefile\");\n" +
3686
			"        final FileReader fileReader = new FileReader(file);\n" +
3687
			"        char[] in = new char[50];\n" +
3688
			"        fileReader.read(in);\n" +
3689
			"        new Runnable() {\n public void run() {\n" +
3690
			"            try {\n" +
3691
			"                fileReader.close();\n" +
3692
			"                FileReader localReader = new FileReader(file);\n" +
3693
			"            } catch (IOException ex) { /* nop */ }\n" +
3694
			"        }}.run();\n" +
3695
			"    }\n" +
3696
			"    public static void main(String[] args) throws IOException {\n" +
3697
			"        new X().foo();\n" +
3698
			"    }\n" +
3699
			"}\n"
3700
		},
3701
		"----------\n" + 
3702
		"1. WARNING in X.java (at line 7)\n" + 
3703
		"	final FileReader fileReader = new FileReader(file);\n" + 
3704
		"	                 ^^^^^^^^^^\n" + 
3705
		"Value of type AutoCloseable is not closed on all paths.\n" + 
3706
		"----------\n" + 
3707
		"2. ERROR in X.java (at line 14)\n" + 
3708
		"	FileReader localReader = new FileReader(file);\n" + 
3709
		"	           ^^^^^^^^^^^\n" + 
3710
		"Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.\n" + 
3711
		"----------\n",
3712
		null,
3713
		true,
3714
		options);
3715
}
3716
// Bug 349326 - [1.7] new warning for missing try-with-resources
3717
// three AutoCloseables in different blocks of the same method
3718
public void test055i() {
3719
	Map options = getCompilerOptions();
3720
	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
3721
	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING);
3722
	options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE);
3723
	this.runNegativeTest(
3724
		new String[] {
3725
			"X.java",
3726
			"import java.io.File;\n" +
3727
			"import java.io.FileReader;\n" +
3728
			"import java.io.IOException;\n" +
3729
			"public class X {\n" +
3730
			"    void foo(boolean f1, boolean f2) throws IOException {\n" +
3731
			"        File file = new File(\"somefile\");\n" +
3732
			"        if (f1) {\n" +
3733
			"            FileReader fileReader = new FileReader(file); // err: not closed\n" +
3734
			"            char[] in = new char[50];\n" +
3735
			"            fileReader.read(in);\n" +
3736
			"            while (true) {\n" +
3737
			"                 FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" +
3738
			"                 loopReader.close();" +
3739
			"                 break;\n" +
3740
			"            }\n" +
3741
			"        } else {\n" +
3742
			"            FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" +
3743
			"            if (f2)\n" +
3744
			"                fileReader.close();\n" +
3745
			"        }\n" +
3746
			"    }\n" +
3747
			"    public static void main(String[] args) throws IOException {\n" +
3748
			"        new X().foo(true, true);\n" +
3749
			"    }\n" +
3750
			"}\n"
3751
		},
3752
		"----------\n" + 
3753
		"1. ERROR in X.java (at line 8)\n" + 
3754
		"	FileReader fileReader = new FileReader(file); // err: not closed\n" + 
3755
		"	           ^^^^^^^^^^\n" + 
3756
		"Value of type AutoCloseable is not closed neither explicitly nor using a try-with-resources.\n" + 
3757
		"----------\n" + 
3758
		"2. WARNING in X.java (at line 16)\n" + 
3759
		"	FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + 
3760
		"	           ^^^^^^^^^^\n" + 
3761
		"Value of type AutoCloseable is not closed on all paths.\n" + 
3762
		"----------\n",
3763
		null,
3764
		true,
3765
		options);
3766
}
3767
// Bug 349326 - [1.7] new warning for missing try-with-resources
3768
// a method uses an AutoCloseable without closing it locally but passing as arg to another method
3769
public void test055j() {
3770
	Map options = getCompilerOptions();
3771
	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
3772
	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
3773
	this.runNegativeTest(
3774
		new String[] {
3775
			"X.java",
3776
			"import java.io.File;\n" +
3777
			"import java.io.FileReader;\n" +
3778
			"import java.io.IOException;\n" +
3779
			"public class X {\n" +
3780
			"    void foo() throws IOException {\n" +
3781
			"        File file = new File(\"somefile\");\n" +
3782
			"        FileReader fileReader = new FileReader(file);\n" +
3783
			"        read(fileReader);\n" +
3784
			"    }\n" +
3785
			"    void read(FileReader reader) { }\n" +
3786
			"    public static void main(String[] args) throws IOException {\n" +
3787
			"        new X().foo();\n" +
3788
			"    }\n" +
3789
			"}\n"
3790
		},
3791
		"----------\n" + 
3792
		"1. ERROR in X.java (at line 7)\n" + 
3793
		"	FileReader fileReader = new FileReader(file);\n" + 
3794
		"	           ^^^^^^^^^^\n" + 
3795
		"Value of type AutoCloseable is not closed on all paths.\n" + 
3796
		"----------\n",
3797
		null,
3798
		true,
3799
		options);
3800
}
3344
public static Class testClass() {
3801
public static Class testClass() {
3345
	return TryWithResourcesStatementTest.class;
3802
	return TryWithResourcesStatementTest.class;
3346
}
3803
}

Return to bug 349326