Index: compiler/org/eclipse/jdt/core/compiler/IProblem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java,v
retrieving revision 1.229
diff -u -r1.229 IProblem.java
--- compiler/org/eclipse/jdt/core/compiler/IProblem.java 23 Aug 2011 06:03:55 -0000 1.229
+++ compiler/org/eclipse/jdt/core/compiler/IProblem.java 23 Aug 2011 16:13:58 -0000
@@ -116,7 +116,12 @@
* Benjamin Muskalla - added the following constants
* MissingSynchronizedModifierInInheritedMethod
* Stephan Herrmann - added the following constants
- * UnusedObjectAllocation
+ * UnusedObjectAllocation
+ * PotentiallyUnclosedCloseable
+ * PotentiallyUnclosedCloseableAtExit
+ * UnclosedCloseable
+ * UnclosedCloseableAtExit
+ * ExplicitlyClosedAutoCloseable
*******************************************************************************/
package org.eclipse.jdt.core.compiler;
@@ -1394,6 +1399,16 @@
int DiamondNotBelow17 = TypeRelated + 883;
/** @since 3.7.1 */
int RedundantSpecificationOfTypeArguments = TypeRelated + 884;
+ /** @since 3.8 */
+ int PotentiallyUnclosedCloseable = Internal + 885;
+ /** @since 3.8 */
+ int PotentiallyUnclosedCloseableAtExit = Internal + 886;
+ /** @since 3.8 */
+ int UnclosedCloseable = Internal + 887;
+ /** @since 3.8 */
+ int UnclosedCloseableAtExit = Internal + 888;
+ /** @since 3.8 */
+ int ExplicitlyClosedAutoCloseable = Internal + 889;
/**
* External problems -- These are problems defined by other plugins
*/
Index: compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java,v
retrieving revision 1.87
diff -u -r1.87 AllocationExpression.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java 28 Jul 2011 17:07:04 -0000 1.87
+++ compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java 23 Aug 2011 16:13:58 -0000
@@ -10,6 +10,7 @@
* Stephan Herrmann - Contributions for
* bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
* bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -42,6 +43,8 @@
// process arguments
if (this.arguments != null) {
for (int i = 0, count = this.arguments.length; i < count; i++) {
+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+ flowInfo = FakedTrackingVariable.markPotentialClosing(this.arguments[i], flowInfo);
flowInfo =
this.arguments[i]
.analyseCode(currentScope, flowContext, flowInfo)
Index: compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java,v
retrieving revision 1.97
diff -u -r1.97 Assignment.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java 28 Jul 2011 17:07:01 -0000 1.97
+++ compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java 23 Aug 2011 16:13:59 -0000
@@ -12,6 +12,7 @@
* bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
* bug 292478 - Report potentially null across variable assignment
* bug 335093 - [compiler][null] minimal hook for future null annotation support
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -47,6 +48,34 @@
flowInfo = ((Reference) this.lhs)
.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
.unconditionalInits();
+ if (local != null) {
+ LocalVariableBinding trackerBinding = null;
+ if (local.closeTracker != null) {
+ // Assigning to a variable already holding an AutoCloseable, has it been closed before?
+ trackerBinding = local.closeTracker.binding;
+ if (!flowInfo.isDefinitelyNull(local)) { // only if previous value may be non-null
+ if (flowInfo.isDefinitelyNull(trackerBinding))
+ currentScope.problemReporter().unclosedCloseable(local.closeTracker, this);
+ else if (flowInfo.isPotentiallyNull(trackerBinding))
+ currentScope.problemReporter().potentiallyUnclosedCloseable(local.closeTracker, this);
+ }
+ }
+ if (FakedTrackingVariable.isAutoCloseable(this.expression.resolvedType)) {
+ if (local.closeTracker != null && local.closeTracker.isInsideTryWithResources) {
+ // re-assigning resource of try-with-resources is a different error
+ } else {
+ // new value is AutoCloseable, start tracking, possibly re-using existing tracker var:
+ if (trackerBinding == null) {
+ local.closeTracker = new FakedTrackingVariable(local, this);
+ trackerBinding = local.closeTracker.binding;
+ }
+ flowInfo.markAsDefinitelyNull(trackerBinding);
+// TODO(stephan): this might be useful, but I could not find a test case for it:
+// if (flowContext.initsOnFinally != null)
+// flowContext.initsOnFinally.markAsDefinitelyNonNull(trackerBinding);
+ }
+ }
+ }
int nullStatus = this.expression.nullStatus(flowInfo);
if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
if (nullStatus == FlowInfo.NULL) {
Index: compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java,v
retrieving revision 1.43
diff -u -r1.43 Block.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/Block.java 14 Oct 2009 18:08:37 -0000 1.43
+++ compiler/org/eclipse/jdt/internal/compiler/ast/Block.java 23 Aug 2011 16:13:59 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -36,6 +37,8 @@
flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
}
}
+ if (this.explicitDeclarations > 0) // if block has its own scope analyze tracking vars now:
+ this.scope.checkUnclosedCloseables(flowInfo, flowContext, null);
return flowInfo;
}
/**
Index: compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
===================================================================
RCS file: compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
diff -N compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Herrmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+/**
+ * A faked local variable declaration used for keeping track of data flows of a
+ * special variable. Certain events will be recorded by changing the null info
+ * for this variable.
+ *
+ * See bug 349326 - [1.7] new warning for missing try-with-resources
+ */
+public class FakedTrackingVariable extends LocalDeclaration {
+
+ /** If resource is already managed by try-with-resources don't complain. */
+ public boolean isInsideTryWithResources;
+
+ /**
+ * If close() is invoked from a nested method (inside a local type)
+ * report remaining problems only as potential.
+ */
+ public boolean closedInNestedMethod;
+
+ /** If a problem has already been reported don't complain again. */
+ public boolean hasReportedProblem;
+
+ MethodScope methodScope; // designates the method declaring this variable
+
+ public LocalVariableBinding originalBinding; // the real local being tracked
+
+ public FakedTrackingVariable(LocalVariableBinding original, Statement location) {
+ super(original.name, location.sourceStart, location.sourceEnd);
+ this.type = new SingleTypeReference(
+ TypeConstants.OBJECT,
+ ((long)this.sourceStart <<32)+this.sourceEnd);
+ this.methodScope = original.declaringScope.methodScope();
+ this.originalBinding = original;
+ resolve(original.declaringScope);
+ }
+
+ public void generateCode(BlockScope currentScope, CodeStream codeStream)
+ { /* NOP - this variable is completely dummy, ie. for analysis only. */ }
+
+ public void resolve (BlockScope scope) {
+ // only need the binding, which is used as reference in FlowInfo methods.
+ this.binding = new LocalVariableBinding(
+ this.name,
+ scope.getJavaLangObject(), // dummy, just needs to be a reference type
+ 0,
+ false);
+ this.binding.setConstant(Constant.NotAConstant);
+ this.binding.useFlag = LocalVariableBinding.USED;
+ // use a free slot without assigning it:
+ this.binding.id = scope.registerTrackingVariable(this);
+ }
+
+ /**
+ * If expression resolves to a local variable binding of type AutoCloseable,
+ * answer the variable that tracks closing of that local, creating it if needed.
+ * @param expression
+ * @return a new {@link FakedTrackingVariable} or null.
+ */
+ public static FakedTrackingVariable getCloseTrackingVariable(Expression expression) {
+ if (expression instanceof SingleNameReference) {
+ SingleNameReference name = (SingleNameReference) expression;
+ if (name.binding instanceof LocalVariableBinding) {
+ LocalVariableBinding local = (LocalVariableBinding)name.binding;
+ if (local.closeTracker != null)
+ return local.closeTracker;
+ if (local.isParameter() || !isAutoCloseable(expression.resolvedType))
+ return null;
+ // tracking var doesn't yet exist. This happens in finally block
+ // which is analyzed before the corresponding try block
+ Statement location = local.declaration;
+ return local.closeTracker = new FakedTrackingVariable(local, location);
+ }
+ }
+ return null;
+ }
+
+ public static FlowInfo markPotentialClosing(Expression expression, FlowInfo flowInfo) {
+ FakedTrackingVariable trackVar = getCloseTrackingVariable(expression);
+ if (trackVar != null) {
+ // insert info that the tracked resource *may* be closed (by the target method, i.e.)
+ FlowInfo infoResourceIsClosed = flowInfo.copy();
+ infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding);
+ return FlowInfo.conditional(flowInfo, infoResourceIsClosed);
+ }
+ return flowInfo;
+ }
+
+ /** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */
+ public static boolean isAutoCloseable(TypeBinding typeBinding) {
+ return typeBinding instanceof ReferenceBinding
+ && ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable);
+ }
+}
Index: compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java,v
retrieving revision 1.71
diff -u -r1.71 IfStatement.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java 5 Mar 2011 17:18:43 -0000 1.71
+++ compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java 23 Aug 2011 16:14:02 -0000
@@ -7,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * Stephan Herrmann - Contributions for
+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -124,6 +126,8 @@
}
elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
}
+ // process AutoCloseable resources closed in only one branch:
+ currentScope.correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
// merge THEN & ELSE initializations
FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranchesIfElse(
thenFlowInfo,
Index: compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java,v
retrieving revision 1.80
diff -u -r1.80 LocalDeclaration.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java 8 Mar 2011 16:46:01 -0000 1.80
+++ compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java 23 Aug 2011 16:14:02 -0000
@@ -11,6 +11,7 @@
* bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
* bug 292478 - Report potentially null across variable assignment
* bug 335093 - [compiler][null] minimal hook for future null annotation support
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -76,6 +77,13 @@
this.initialization
.analyseCode(currentScope, flowContext, flowInfo)
.unconditionalInits();
+ if (FakedTrackingVariable.isAutoCloseable(this.initialization.resolvedType)) {
+ this.binding.closeTracker = new FakedTrackingVariable(this.binding, this);
+ flowInfo.markAsDefinitelyNull(this.binding.closeTracker.binding);
+// TODO(stephan): this might be useful, but I could not find a test case for it:
+// if (flowContext.initsOnFinally != null)
+// flowContext.initsOnFinally.markAsDefinitelyNonNull(this.binding.closeTracker.binding);
+ }
int nullStatus = this.initialization.nullStatus(flowInfo);
if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
this.bits |= FirstAssignmentToLocal;
Index: compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java,v
retrieving revision 1.153
diff -u -r1.153 MessageSend.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 28 Jul 2011 17:07:01 -0000 1.153
+++ compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java 23 Aug 2011 16:14:02 -0000
@@ -8,7 +8,9 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * Stephan Herrmann - Contributions for
+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -38,6 +40,7 @@
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
@@ -60,6 +63,21 @@
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
boolean nonStatic = !this.binding.isStatic();
flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
+ // recording the closing of AutoCloseable resources:
+ if (CharOperation.equals(TypeConstants.CLOSE, this.selector))
+ {
+ FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.receiver);
+ if (trackingVariable != null) { // null happens if receiver is not a local variable or not an AutoCloseable
+ if (trackingVariable.methodScope == currentScope.methodScope()) {
+ flowInfo.markAsDefinitelyNonNull(trackingVariable.binding);
+// TODO(stephan): this might be useful, but I could not find a test case for it:
+// if (flowContext.initsOnFinally != null)
+// flowContext.initsOnFinally.markAsDefinitelyNonNull(trackingVariable.binding);
+ } else {
+ trackingVariable.closedInNestedMethod = true;
+ }
+ }
+ }
if (nonStatic) {
this.receiver.checkNPE(currentScope, flowContext, flowInfo);
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682
@@ -80,6 +98,8 @@
if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
}
+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+ flowInfo = FakedTrackingVariable.markPotentialClosing(this.arguments[i], flowInfo);
flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
}
}
Index: compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java,v
retrieving revision 1.80
diff -u -r1.80 MethodDeclaration.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 5 Mar 2011 17:18:43 -0000 1.80
+++ compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java 23 Aug 2011 16:14:02 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -134,6 +135,7 @@
}
}
+ this.scope.checkUnclosedCloseables(flowInfo, methodContext, null/*don't report against a specific location*/);
} catch (AbortMethod e) {
this.ignoreFurtherInvestigation = true;
}
Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java,v
retrieving revision 1.103
diff -u -r1.103 QualifiedAllocationExpression.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java 28 Jul 2011 17:07:04 -0000 1.103
+++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java 23 Aug 2011 16:14:02 -0000
@@ -7,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * Stephan Herrmann - Contributions for
+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -72,6 +74,8 @@
// process arguments
if (this.arguments != null) {
for (int i = 0, count = this.arguments.length; i < count; i++) {
+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+ flowInfo = FakedTrackingVariable.markPotentialClosing(this.arguments[i], flowInfo);
flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
Index: compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java,v
retrieving revision 1.71
diff -u -r1.71 ReturnStatement.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java 27 Apr 2011 15:44:15 -0000 1.71
+++ compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java 23 Aug 2011 16:14:02 -0000
@@ -7,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * Stephan Herrmann - Contributions for
+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -40,6 +42,13 @@
if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
this.expression.checkNPE(currentScope, flowContext, flowInfo);
}
+ FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
+ if (trackingVariable != null) {
+ // don't report issues concerning this local, since by returning
+ // the method passes the responsibility to the caller:
+ flowInfo.markAsDefinitelyNonNull(trackingVariable.binding);
+ trackingVariable.hasReportedProblem = true;
+ }
}
this.initStateIndex =
currentScope.methodScope().recordInitializationStates(flowInfo);
@@ -104,6 +113,7 @@
this.expression.bits |= ASTNode.IsReturnedValue;
}
}
+ currentScope.checkUnclosedCloseables(flowInfo, null/*ignore exception exits from flowContext*/, this);
return FlowInfo.DEAD_END;
}
Index: compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java,v
retrieving revision 1.121
diff -u -r1.121 TryStatement.java
--- compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 18 Aug 2011 17:07:34 -0000 1.121
+++ compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 23 Aug 2011 16:14:03 -0000
@@ -7,10 +7,15 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 332637 - Dead Code detection removing code that isn't dead
+ * Stephan Herrmann - Contributions for
+ * bug 332637 - Dead Code detection removing code that isn't dead
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
@@ -124,8 +129,13 @@
for (int i = 0; i < resourcesLength; i++) {
flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
- this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
- TypeBinding type = this.resources[i].binding.type;
+ LocalVariableBinding resourceBinding = this.resources[i].binding;
+ resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+ if (resourceBinding.closeTracker != null) {
+ resourceBinding.closeTracker.isInsideTryWithResources = true;
+ flowInfo.markAsDefinitelyNonNull(resourceBinding.closeTracker.binding); // all is well
+ }
+ TypeBinding type = resourceBinding.type;
if (type != null && type.isValidBinding()) {
ReferenceBinding binding = (ReferenceBinding) type;
MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
@@ -250,8 +260,13 @@
for (int i = 0; i < resourcesLength; i++) {
flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo);
- this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
- TypeBinding type = this.resources[i].binding.type;
+ LocalVariableBinding resourceBinding = this.resources[i].binding;
+ resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+ if (resourceBinding.closeTracker != null) {
+ resourceBinding.closeTracker.isInsideTryWithResources = true;
+ flowInfo.markAsDefinitelyNonNull(resourceBinding.closeTracker.binding); // all is well
+ }
+ TypeBinding type = resourceBinding.type;
if (type != null && type.isValidBinding()) {
ReferenceBinding binding = (ReferenceBinding) type;
MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
@@ -271,7 +286,13 @@
if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
this.bits |= ASTNode.IsTryBlockExiting;
}
-
+ // superimpose status for tracking variables:
+ // don't complain on initsOnException if finally has a better state.
+ List trackVars = new ArrayList();
+ currentScope.getTrackVars(trackVars, subInfo);
+ if (trackVars.size() > 0)
+ flowContext.improveNullInfoForExceptionExits(trackVars, subInfo);
+
// check unreachable catch blocks
handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);
Index: compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java,v
retrieving revision 1.47
diff -u -r1.47 ExceptionHandlingFlowContext.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java 28 Jul 2011 17:07:43 -0000 1.47
+++ compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java 23 Aug 2011 16:14:03 -0000
@@ -7,22 +7,26 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
import java.util.ArrayList;
+import java.util.List;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
@@ -180,7 +184,14 @@
return node;
}
-
+public int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo) {
+ // collect info from normal flow and exceptional flows:
+ int status = flowInfo.nullStatus(local);
+ if (this.initsOnExceptions != null)
+ for (int i = 0; i < this.initsOnExceptions.length; i++)
+ status |= (this.initsOnExceptions[i].nullStatus(local) & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL));
+ return status;
+}
public String individualToString() {
StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
@@ -298,4 +309,31 @@
}
return null;
}
+/**
+ * {@inheritDoc}
+ */
+public void improveNullInfoForExceptionExits(List moreTrackVars, FlowInfo otherInfo) {
+ if (this.initsOnExceptions == null) return;
+ for (int j = 0; j < this.initsOnExceptions.length; j++) {
+ UnconditionalFlowInfo copy = null;
+ for (int i = 0; i < moreTrackVars.size(); i++) {
+ LocalVariableBinding trackVar = ((FakedTrackingVariable) moreTrackVars.get(i)).binding;
+ int status = otherInfo.nullStatus(trackVar);
+ if ((status & FlowInfo.NULL) == 0) {
+ if ((status & FlowInfo.NON_NULL) != 0) {
+ this.initsOnExceptions[j].markAsDefinitelyNonNull(trackVar);
+ } else if ((status & FlowInfo.POTENTIALLY_NON_NULL) != 0) {
+ if (this.initsOnExceptions[j].isDefinitelyNull(trackVar)) {
+ // cannot directly set to pot.nn, need to construct and merge infos for this task:
+ if (copy == null)
+ copy = this.initsOnExceptions[j].unconditionalCopy();
+ copy.markAsDefinitelyNonNull(trackVar);
+ }
+ }
+ }
+ }
+ if (copy != null)
+ this.initsOnExceptions[j] = this.initsOnExceptions[j].mergedWith(copy);
+ }
+}
}
Index: compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java,v
retrieving revision 1.71
diff -u -r1.71 FlowContext.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 28 Jul 2011 17:07:43 -0000 1.71
+++ compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java 23 Aug 2011 16:14:03 -0000
@@ -7,13 +7,16 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
import org.eclipse.jdt.internal.compiler.ast.Reference;
@@ -391,6 +394,14 @@
return null;
}
+/**
+ * Answer the combined null status that local will have after this flow context.
+ * Subclasses will respect break and exception exits.
+ */
+public int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo) {
+ return flowInfo.nullStatus(local);
+}
+
/*
* lookup through break labels
*/
@@ -732,4 +743,41 @@
buffer.append(individualToString()).append('\n');
return buffer.toString();
}
+/**
+ * For all tracking variables in the given list improve the null info in initsOnException (if existent)
+ * with information from the given otherInfo.
+ */
+public void improveNullInfoForExceptionExits(List moreTrackVars, FlowInfo otherInfo) {
+ // nothing here, overridden in ExceptionHandlingFlowContext
+}
+
+/**
+ * Get the null status that local will have after the current point as indicated by flowInfo and flowContext
+ * @param local
+ * @param flowInfo
+ * @param flowContext may be null
+ * @return a bitset from the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}.
+ */
+public static int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo, FlowContext flowContext) {
+ int status = (flowContext != null)
+ ? flowContext.getNullStatusAfter(local, flowInfo)
+ : flowInfo.nullStatus(local);
+ // at this point some combinations are not useful so flatten to a single bit:
+ return mergeNullStatus(status);
+}
+
+/* Merge the bits NULL, NON_NULL, POTENTIALLY_NULL, POTENTIALLY_NON_NULL to a one-bit answer. */
+private static int mergeNullStatus(int status) {
+ if ((status & FlowInfo.NULL) != 0) {
+ if ((status & (FlowInfo.NON_NULL | FlowInfo.POTENTIALLY_NON_NULL)) != 0)
+ return FlowInfo.POTENTIALLY_NULL; // null + doubt = pot null
+ return FlowInfo.NULL;
+ } else if ((status & FlowInfo.NON_NULL) != 0) {
+ if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
+ return FlowInfo.POTENTIALLY_NULL; // non-null + doubt = pot null
+ return FlowInfo.NON_NULL;
+ } else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
+ return FlowInfo.POTENTIALLY_NULL;
+ return status;
+}
}
Index: compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java,v
retrieving revision 1.33
diff -u -r1.33 SwitchFlowContext.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java 8 Mar 2011 16:46:01 -0000 1.33
+++ compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java 23 Aug 2011 16:14:03 -0000
@@ -7,11 +7,13 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
/**
* Reflects the context of code analysis, keeping track of enclosing
@@ -31,6 +33,14 @@
return this.breakLabel;
}
+public int getNullStatusAfter(LocalVariableBinding local, FlowInfo flowInfo) {
+ // collect info from normal flow and breaks flows:
+ int status = flowInfo.nullStatus(local);
+ if (this.initsOnBreak != null)
+ status |= this.initsOnBreak.nullStatus(local);
+ return status;
+}
+
public String individualToString() {
StringBuffer buffer = new StringBuffer("Switch flow context"); //$NON-NLS-1$
buffer.append("[initsOnBreak -").append(this.initsOnBreak.toString()).append(']'); //$NON-NLS-1$
Index: compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java,v
retrieving revision 1.75
diff -u -r1.75 UnconditionalFlowInfo.java
--- compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 12 Apr 2011 05:27:06 -0000 1.75
+++ compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 23 Aug 2011 16:14:03 -0000
@@ -13,6 +13,7 @@
* bug 292478 - Report potentially null across variable assignment
* bug 332637 - Dead Code detection removing code that isn't dead
* bug 341499 - [compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
@@ -770,7 +771,7 @@
}
int vectorIndex;
if ((vectorIndex = (position / BitCacheSize) - 1)
- >= this.extra[0].length) {
+ >= this.extra[2].length) {
return false; // if not enough room in vector, then not initialized
}
return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
@@ -797,7 +798,7 @@
}
int vectorIndex;
if ((vectorIndex = (position / BitCacheSize) - 1) >=
- this.extra[0].length) {
+ this.extra[2].length) {
return false; // if not enough room in vector, then not initialized
}
return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
@@ -822,7 +823,7 @@
}
int vectorIndex;
if ((vectorIndex = (position / BitCacheSize) - 1) >=
- this.extra[0].length) {
+ this.extra[2].length) {
return false; // if not enough room in vector, then not initialized
}
return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex]
@@ -882,7 +883,7 @@
}
int vectorIndex;
if ((vectorIndex = (position / BitCacheSize) - 1) >=
- this.extra[0].length) {
+ this.extra[2].length) {
return false; // if not enough room in vector, then not initialized
}
return ((this.extra[4][vectorIndex]
@@ -908,7 +909,7 @@
}
int vectorIndex;
if ((vectorIndex = (position / BitCacheSize) - 1) >=
- this.extra[0].length) {
+ this.extra[2].length) {
return false; // if not enough room in vector, then not initialized
}
return ((this.extra[3][vectorIndex]
@@ -934,7 +935,7 @@
}
int vectorIndex;
if ((vectorIndex = (position / BitCacheSize) - 1) >=
- this.extra[0].length) {
+ this.extra[2].length) {
return false; // if not enough room in vector, then not initialized
}
return (this.extra[5][vectorIndex]
Index: compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java,v
retrieving revision 1.245
diff -u -r1.245 CompilerOptions.java
--- compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 28 Jul 2011 17:07:39 -0000 1.245
+++ compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 23 Aug 2011 16:14:07 -0000
@@ -8,8 +8,10 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Muskalla - Contribution for bug 239066
- * Stephan Herrmann - Contribution for bug 236385
- * Stephan Herrmann - Contribution for bug 295551
+ * Stephan Herrmann - Contributions for
+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ * bug 295551 - Add option to automatically promote all warnings to errors
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.impl;
@@ -137,6 +139,9 @@
public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic"; //$NON-NLS-1$
public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
public static final String OPTION_ReportRedundantSpecificationOfTypeArguments = "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$
+ public static final String OPTION_ReportUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.unclosedCloseable"; //$NON-NLS-1$
+ public static final String OPTION_ReportPotentiallyUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
+ public static final String OPTION_ReportExplicitlyClosedAutoCloseable = "org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
/**
* Possible values for configurable options
*/
@@ -240,6 +245,9 @@
public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
public static final int RedundantSpecificationOfTypeArguments = IrritantSet.GROUP2 | ASTNode.Bit7;
+ public static final int UnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit8;
+ public static final int PotentiallyUnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit9;
+ public static final int ExplicitlyClosedAutoCloseable = IrritantSet.GROUP2 | ASTNode.Bit10;
// Severity level for handlers
/**
@@ -376,8 +384,9 @@
"javadoc", //$NON-NLS-1$
"nls", //$NON-NLS-1$
"null", //$NON-NLS-1$
- "restriction", //$NON-NLS-1$
"rawtypes", //$NON-NLS-1$
+ "resource", //$NON-NLS-1$
+ "restriction", //$NON-NLS-1$
"serial", //$NON-NLS-1$
"static-access", //$NON-NLS-1$
"static-method", //$NON-NLS-1$
@@ -551,6 +560,12 @@
return OPTION_ReportMethodCanBePotentiallyStatic;
case RedundantSpecificationOfTypeArguments :
return OPTION_ReportRedundantSpecificationOfTypeArguments;
+ case UnclosedCloseable :
+ return OPTION_ReportUnclosedCloseable;
+ case PotentiallyUnclosedCloseable :
+ return OPTION_ReportPotentiallyUnclosedCloseable;
+ case ExplicitlyClosedAutoCloseable :
+ return OPTION_ReportExplicitlyClosedAutoCloseable;
}
return null;
}
@@ -714,6 +729,9 @@
OPTION_ReportUnusedTypeArgumentsForMethodInvocation,
OPTION_ReportUnusedWarningToken,
OPTION_ReportVarargsArgumentNeedCast,
+ OPTION_ReportUnclosedCloseable,
+ OPTION_ReportPotentiallyUnclosedCloseable,
+ OPTION_ReportExplicitlyClosedAutoCloseable,
};
return result;
}
@@ -784,10 +802,14 @@
case MethodCanBeStatic :
case MethodCanBePotentiallyStatic :
return "static-method"; //$NON-NLS-1$
+ case PotentiallyUnclosedCloseable:
+ case UnclosedCloseable:
+ case ExplicitlyClosedAutoCloseable:
+ return "resource"; //$NON-NLS-1$
case InvalidJavadoc :
case MissingJavadocComments :
case MissingJavadocTags:
- return "javadoc"; //$NON-NLS-1$
+ return "javadoc"; //$NON-NLS-1$
}
return null;
}
@@ -841,6 +863,8 @@
case 'r' :
if ("rawtypes".equals(warningToken)) //$NON-NLS-1$
return IrritantSet.RAW;
+ if ("resource".equals(warningToken)) //$NON-NLS-1$
+ return IrritantSet.RESOURCE;
if ("restriction".equals(warningToken)) //$NON-NLS-1$
return IrritantSet.RESTRICTION;
break;
@@ -980,6 +1004,9 @@
optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments));
+ optionsMap.put(OPTION_ReportUnclosedCloseable, getSeverityString(UnclosedCloseable));
+ optionsMap.put(OPTION_ReportPotentiallyUnclosedCloseable, getSeverityString(PotentiallyUnclosedCloseable));
+ optionsMap.put(OPTION_ReportExplicitlyClosedAutoCloseable, getSeverityString(ExplicitlyClosedAutoCloseable));
return optionsMap;
}
@@ -1410,6 +1437,9 @@
if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportRedundantSpecificationOfTypeArguments)) != null) updateSeverity(RedundantSpecificationOfTypeArguments, optionValue);
+ if ((optionValue = optionsMap.get(OPTION_ReportUnclosedCloseable)) != null) updateSeverity(UnclosedCloseable, optionValue);
+ if ((optionValue = optionsMap.get(OPTION_ReportPotentiallyUnclosedCloseable)) != null) updateSeverity(PotentiallyUnclosedCloseable, optionValue);
+ if ((optionValue = optionsMap.get(OPTION_ReportExplicitlyClosedAutoCloseable)) != null) updateSeverity(ExplicitlyClosedAutoCloseable, optionValue);
// Javadoc options
if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
@@ -1625,6 +1655,9 @@
buf.append("\n\t- method can be static: ").append(getSeverityString(MethodCanBeStatic)); //$NON-NLS-1$
buf.append("\n\t- method can be potentially static: ").append(getSeverityString(MethodCanBePotentiallyStatic)); //$NON-NLS-1$
buf.append("\n\t- redundant specification of type arguments: ").append(getSeverityString(RedundantSpecificationOfTypeArguments)); //$NON-NLS-1$
+ buf.append("\n\t- resource is not closed: ").append(getSeverityString(UnclosedCloseable)); //$NON-NLS-1$
+ buf.append("\n\t- resource may not be closed: ").append(getSeverityString(PotentiallyUnclosedCloseable)); //$NON-NLS-1$
+ buf.append("\n\t- resource should be handled by try-with-resources: ").append(getSeverityString(ExplicitlyClosedAutoCloseable)); //$NON-NLS-1$
return buf.toString();
}
Index: compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java,v
retrieving revision 1.15
diff -u -r1.15 IrritantSet.java
--- compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java 28 Jul 2011 17:07:39 -0000 1.15
+++ compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java 23 Aug 2011 16:14:07 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.impl;
@@ -57,6 +58,7 @@
public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
+ public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable);
public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default
@@ -99,7 +101,8 @@
// group-2 warnings enabled by default
.set(
CompilerOptions.DeadCode
- |CompilerOptions.Tasks);
+ |CompilerOptions.Tasks
+ |CompilerOptions.UnclosedCloseable);
ALL.setAll();
HIDING
@@ -124,6 +127,9 @@
.set(CompilerOptions.RedundantSpecificationOfTypeArguments);
STATIC_METHOD
.set(CompilerOptions.MethodCanBePotentiallyStatic);
+ RESOURCE
+ .set(CompilerOptions.PotentiallyUnclosedCloseable)
+ .set(CompilerOptions.ExplicitlyClosedAutoCloseable);
String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$
UNCHECKED.set(CompilerOptions.RawTypeReference);
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java,v
retrieving revision 1.136
diff -u -r1.136 BinaryTypeBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 17 Jan 2011 13:00:56 -0000 1.136
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 23 Aug 2011 16:14:07 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -971,6 +972,12 @@
variable.resolve();
return variable;
}
+public boolean hasTypeBit(int bit) {
+ // ensure hierarchy is resolved, which will propagate bits down to us
+ superclass();
+ superInterfaces();
+ return (this.typeBits & bit) != 0;
+}
private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) {
// ParameterSignature = Identifier ':' TypeSignature
// or Identifier ':' TypeSignature(optional) InterfaceBound(s)
@@ -1139,8 +1146,14 @@
// finish resolving the type
this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */);
this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
- if (this.superclass.problemId() == ProblemReasons.NotFound)
+ if (this.superclass.problemId() == ProblemReasons.NotFound) {
this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
+ } else {
+ // make super-type resolving recursive for propagating typeBits downwards
+ this.superclass.superclass();
+ this.superclass.superInterfaces();
+ }
+ this.typeBits |= this.superclass.typeBits;
return this.superclass;
}
// NOTE: superInterfaces of binary types are resolved when needed
@@ -1150,8 +1163,14 @@
for (int i = this.superInterfaces.length; --i >= 0;) {
this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */);
- if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound)
+ if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) {
this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
+ } else {
+ // make super-type resolving recursive for propagating typeBits downwards
+ this.superInterfaces[i].superclass();
+ this.superInterfaces[i].superInterfaces();
+ }
+ this.typeBits |= this.superInterfaces[i].typeBits;
}
this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
return this.superInterfaces;
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java,v
retrieving revision 1.126
diff -u -r1.126 BlockScope.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java 28 Jul 2011 17:07:22 -0000 1.126
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java 23 Aug 2011 16:14:08 -0000
@@ -7,13 +7,19 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -957,4 +963,99 @@
}
}
}
+
+private List trackingVariables; // can be null if no resources are tracked
+/**
+ * Register a tracking variable and compute its id.
+ */
+public int registerTrackingVariable(FakedTrackingVariable fakedTrackingVariable) {
+ if (this.trackingVariables == null)
+ this.trackingVariables = new ArrayList();
+ this.trackingVariables.add(fakedTrackingVariable);
+ MethodScope outerMethodScope = outerMostMethodScope();
+ return outerMethodScope.analysisIndex + (++outerMethodScope.trackVarCount);
+
+}
+/**
+ * At the end of a block check the closing-status of all tracked closeables that are declared in this block.
+ */
+public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location) {
+ if (this.trackingVariables == null) return;
+ for (int i=0; i= ClassFileConstants.JDK1_7
+ && !trackingVar.isInsideTryWithResources)
+ problemReporter().explicitlyClosedAutoCloseable(trackingVar);
+ }
+ }
+}
+/**
+ * Find all tracking variables in scope that have relevant null status.
+ * @param moreTrackVars list for collecting all found tracking variables
+ * @param flowInfo use to check if tracking variable has interesting status
+ */
+public void getTrackVars(List moreTrackVars, FlowInfo flowInfo) {
+ if (this.trackingVariables != null) {
+ for (int i=0; i always closed
+ }
+ else if ( elseFlowInfo.isDefinitelyNonNull(trackingVar.binding) // closed in else branch
+ && thenFlowInfo.isDefinitelyNull(trackingVar.originalBinding)) // null in then branch
+ {
+ thenFlowInfo.markAsDefinitelyNonNull(trackingVar.binding); // -> always closed
+ }
+ }
+ }
+ if (this.parent instanceof BlockScope)
+ ((BlockScope) this.parent).correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
+}
}
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java,v
retrieving revision 1.186
diff -u -r1.186 ClassScope.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 12 Aug 2011 20:40:56 -0000 1.186
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 23 Aug 2011 16:14:08 -0000
@@ -11,6 +11,7 @@
* Bug 328281 - visibility leaks not detected when analyzing unused field in private class
* Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
* Bug 354536 - compiling package-info.java still depends on the order of compilation units
+ * Bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -908,6 +909,7 @@
} else {
// only want to reach here when no errors are reported
sourceType.superclass = superclass;
+ sourceType.typeBits |= superclass.typeBits;
return true;
}
}
@@ -1023,6 +1025,7 @@
noProblems &= superInterfaceRef.resolvedType.isValidBinding();
}
// only want to reach here when no errors are reported
+ sourceType.typeBits |= superInterface.typeBits;
interfaceBindings[count++] = superInterface;
}
// hold onto all correctly resolved superinterfaces
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java,v
retrieving revision 1.50
diff -u -r1.50 LocalVariableBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java 28 Jul 2011 17:07:23 -0000 1.50
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java 23 Aug 2011 16:14:08 -0000
@@ -7,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ * Stephan Herrmann - Contributions for
+ * bug 185682 - Increment/decrement operators mark local variables as read
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -15,6 +17,7 @@
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.impl.Constant;
@@ -35,6 +38,8 @@
public int[] initializationPCs;
public int initializationCount = 0;
+ public FakedTrackingVariable closeTracker; // track closing of instances of type AutoCloseable, maybe null
+
// for synthetic local variables
// if declaration slot is not positionned, the variable will not be listed in attribute
// 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)
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java,v
retrieving revision 1.79
diff -u -r1.79 MethodScope.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java 8 Mar 2011 16:46:01 -0000 1.79
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java 23 Aug 2011 16:14:08 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -49,6 +50,9 @@
// inner-emulation
public SyntheticArgumentBinding[] extraSyntheticArguments;
+ // count number of tracking variables, see FakedTrackingVariable
+ int trackVarCount;
+
public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) {
super(METHOD_SCOPE, parent);
this.locals = new LocalVariableBinding[5];
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java,v
retrieving revision 1.120
diff -u -r1.120 ParameterizedTypeBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 23 Dec 2010 13:57:49 -0000 1.120
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 23 Aug 2011 16:14:08 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -629,6 +630,13 @@
return this.type.hasMemberTypes();
}
+ public boolean hasTypeBit(int bit) {
+ TypeBinding erasure = erasure();
+ if (erasure instanceof ReferenceBinding)
+ return ((ReferenceBinding) erasure).hasTypeBit(bit);
+ return false;
+ }
+
/**
* @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding)
*/
@@ -955,8 +963,12 @@
// lazy init, since cannot do so during binding creation if during supertype connection
if (currentType.arguments == null)
currentType.initializeArguments(); // only for raw types
- if (currentType.arguments != null)
- return currentType.arguments[originalVariable.rank];
+ if (currentType.arguments != null) {
+ if (currentType.arguments.length == 0) { // diamond type
+ return originalVariable;
+ }
+ return currentType.arguments[originalVariable.rank];
+ }
}
// recurse on enclosing type, as it may hold more substitutions to perform
if (currentType.isStatic()) break;
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java,v
retrieving revision 1.22
diff -u -r1.22 ProblemReferenceBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java 27 Jun 2008 16:04:02 -0000 1.22
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java 23 Aug 2011 16:14:09 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -40,6 +41,12 @@
return this.closestMatch;
}
+public boolean hasTypeBit(int bit) {
+ if (this.closestMatch != null)
+ return this.closestMatch.hasTypeBit(bit);
+ return false;
+}
+
/* API
* Answer the problem id associated with the receiver.
* NoError if the receiver is a valid binding.
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java,v
retrieving revision 1.143
diff -u -r1.143 ReferenceBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 28 Jul 2011 17:07:23 -0000 1.143
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 23 Aug 2011 16:14:09 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -41,7 +42,11 @@
private SimpleLookupTable compatibleCache;
- public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */};
+ int typeBits; // additional bits characterizing this type
+
+ public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */
+ public boolean hasTypeBit(int bit) { return false; }
+ };
private static final Comparator FIELD_COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2) {
@@ -424,8 +429,10 @@
case 'A' :
switch(typeName.length) {
case 13 :
- if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2]))
+ if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
this.id = TypeIds.T_JavaLangAutoCloseable;
+ this.typeBits |= TypeIds.BitAutoCloseable;
+ }
return;
case 14:
if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
@@ -923,6 +930,8 @@
public final boolean hasRestrictedAccess() {
return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
}
+/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */
+abstract public boolean hasTypeBit(int bit);
/** Answer true if the receiver implements anInterface or is identical to anInterface.
* If searchHierarchy is true, then also search the receiver's superclasses.
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java,v
retrieving revision 1.192
diff -u -r1.192 SourceTypeBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 18 Aug 2011 10:02:45 -0000 1.192
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java 23 Aug 2011 16:14:09 -0000
@@ -7,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ * Stephan Herrmann - Contributions for
+ * bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -1063,6 +1065,11 @@
return accessors[1];
}
+public boolean hasTypeBit(int bit) {
+ // source types initialize type bits during connectSuperclass/interfaces()
+ return (this.typeBits & bit) != 0;
+}
+
/**
* @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
*/
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java,v
retrieving revision 1.52
diff -u -r1.52 TypeConstants.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java 28 Jul 2011 17:07:23 -0000 1.52
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java 23 Aug 2011 16:14:09 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -150,6 +151,7 @@
"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
};
char[][] JAVA_LANG_AUTOCLOSEABLE = {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
+ char[] CLOSE = "close".toCharArray(); //$NON-NLS-1$
// Constraints for generic type argument inference
int CONSTRAINT_EQUAL = 0; // Actual = Formal
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java,v
retrieving revision 1.39
diff -u -r1.39 TypeIds.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java 1 Aug 2011 05:37:22 -0000 1.39
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java 23 Aug 2011 16:14:09 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -177,4 +178,10 @@
final int Object2boolean = T_JavaLangObject + (T_boolean << 4);
final int BOXING = 0x200;
final int UNBOXING = 0x400;
+
+ /**
+ * Marks all sub-types of java.lang.AutoCloseable.
+ * @see ReferenceBinding#hasTypeBit(int)
+ */
+ final int BitAutoCloseable = 1;
}
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java,v
retrieving revision 1.75
diff -u -r1.75 TypeVariableBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 25 Oct 2010 08:50:02 -0000 1.75
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 23 Aug 2011 16:14:11 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
+ * Stephan Herrmann - Contributions for
+ * bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -42,6 +44,7 @@
this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
this.tagBits |= TagBits.HasTypeVariable;
this.environment = environment;
+ this.typeBits = -1;
}
/**
@@ -307,6 +310,19 @@
return true;
}
+ public boolean hasTypeBit(int bit) {
+ if (this.typeBits == -1) {
+ // initialize from bounds
+ this.typeBits = 0;
+ if (this.superclass != null)
+ this.typeBits |= this.superclass.typeBits;
+ if (this.superInterfaces != null)
+ for (int i = 0, l = this.superInterfaces.length; i < l; i++)
+ this.typeBits |= this.superInterfaces[i].typeBits;
+ }
+ return (this.typeBits & bit) != 0;
+ }
+
/**
* Returns true if the type variable is directly bound to a given type
*/
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java,v
retrieving revision 1.32
diff -u -r1.32 UnresolvedReferenceBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java 27 Jun 2008 16:04:02 -0000 1.32
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java 23 Aug 2011 16:14:11 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -41,6 +42,10 @@
public String debugName() {
return toString();
}
+public boolean hasTypeBit(int bit) {
+ // shouldn't happen since we are not called before analyseCode(), but play safe:
+ return false;
+}
ReferenceBinding resolve(LookupEnvironment environment, boolean convertGenericToRawType) {
ReferenceBinding targetType = this.resolvedType;
if (targetType == null) {
Index: compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java,v
retrieving revision 1.76
diff -u -r1.76 WildcardBinding.java
--- compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java 24 Jun 2009 18:21:59 -0000 1.76
+++ compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java 23 Aug 2011 16:14:11 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -54,6 +55,7 @@
if (bound instanceof UnresolvedReferenceBinding)
((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
this.tagBits |= TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
+ this.typeBits = -1;
}
public int kind() {
@@ -420,6 +422,19 @@
return this.genericType.hashCode();
}
+ public boolean hasTypeBit(int bit) {
+ if (this.typeBits == -1) {
+ // initialize from upper bounds
+ this.typeBits = 0;
+ if (this.superclass != null)
+ this.typeBits |= this.superclass.typeBits;
+ if (this.superInterfaces != null)
+ for (int i = 0, l = this.superInterfaces.length; i < l; i++)
+ this.typeBits |= this.superInterfaces[i].typeBits;
+ }
+ return (this.typeBits & bit) != 0;
+ }
+
void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
this.genericType = someGenericType;
this.bound = someBound;
Index: compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java,v
retrieving revision 1.439
diff -u -r1.439 ProblemReporter.java
--- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 23 Aug 2011 06:03:55 -0000 1.439
+++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 23 Aug 2011 16:14:12 -0000
@@ -11,6 +11,7 @@
* Stephan Herrmann - Contributions for
* bug 236385 -
* bug 338303 - Warning about Redundant assignment conflicts with definite assignment
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.problem;
@@ -51,6 +52,7 @@
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
@@ -426,6 +428,15 @@
case IProblem.MethodCanBePotentiallyStatic:
return CompilerOptions.MethodCanBePotentiallyStatic;
+
+ case IProblem.UnclosedCloseable:
+ case IProblem.UnclosedCloseableAtExit:
+ return CompilerOptions.UnclosedCloseable;
+ case IProblem.PotentiallyUnclosedCloseable:
+ case IProblem.PotentiallyUnclosedCloseableAtExit:
+ return CompilerOptions.PotentiallyUnclosedCloseable;
+ case IProblem.ExplicitlyClosedAutoCloseable:
+ return CompilerOptions.ExplicitlyClosedAutoCloseable;
case IProblem.RedundantSpecificationOfTypeArguments:
return CompilerOptions.RedundantSpecificationOfTypeArguments;
@@ -461,6 +472,7 @@
case CompilerOptions.ParameterAssignment :
case CompilerOptions.MethodCanBeStatic :
case CompilerOptions.MethodCanBePotentiallyStatic :
+ case CompilerOptions.ExplicitlyClosedAutoCloseable :
return CategorizedProblem.CAT_CODE_STYLE;
case CompilerOptions.MaskedCatchBlock :
@@ -482,6 +494,8 @@
case CompilerOptions.ShouldImplementHashcode :
case CompilerOptions.DeadCode :
case CompilerOptions.UnusedObjectAllocation :
+ case CompilerOptions.UnclosedCloseable :
+ case CompilerOptions.PotentiallyUnclosedCloseable :
return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
case CompilerOptions.OverriddenPackageDefaultMethod :
@@ -7927,4 +7941,51 @@
location.sourceEnd);
}
}
+public void potentiallyUnclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
+ String[] args = { String.valueOf(trackVar.name) };
+ if (location == null) {
+ this.handle(
+ IProblem.PotentiallyUnclosedCloseable,
+ args,
+ args,
+ trackVar.sourceStart,
+ trackVar.sourceEnd);
+ } else {
+ this.handle(
+ IProblem.PotentiallyUnclosedCloseableAtExit,
+ args,
+ args,
+ location.sourceStart,
+ location.sourceEnd);
+ }
+ trackVar.hasReportedProblem = true;
+}
+public void unclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
+ String[] args = { String.valueOf(trackVar.name) };
+ if (location == null) {
+ this.handle(
+ IProblem.UnclosedCloseable,
+ args,
+ args,
+ trackVar.sourceStart,
+ trackVar.sourceEnd);
+ } else {
+ this.handle(
+ IProblem.UnclosedCloseableAtExit,
+ args,
+ args,
+ location.sourceStart,
+ location.sourceEnd);
+ }
+ trackVar.hasReportedProblem = true;
+}
+public void explicitlyClosedAutoCloseable(FakedTrackingVariable trackVar) {
+ String[] args = { String.valueOf(trackVar.name) };
+ this.handle(
+ IProblem.ExplicitlyClosedAutoCloseable,
+ args,
+ args,
+ trackVar.sourceStart,
+ trackVar.sourceEnd);
+}
}
\ No newline at end of file
Index: compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties,v
retrieving revision 1.269
diff -u -r1.269 messages.properties
--- compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 23 Aug 2011 06:03:55 -0000 1.269
+++ compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 23 Aug 2011 16:14:12 -0000
@@ -8,7 +8,9 @@
# Contributors:
# IBM Corporation - initial API and implementation
# Benjamin Muskalla - Contribution for bug 239066
-# Stephan Herrmann - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+# Stephan Herrmann - Contributions for
+# bug 185682 - Increment/decrement operators mark local variables as read
+# bug 349326 - [1.7] new warning for missing try-with-resources
###############################################################################
0 = {0}
1 = super cannot be used in java.lang.Object
@@ -644,6 +646,11 @@
882 = Unhandled exception type {0} thrown by automatic close() invocation on {1}
883 = '<>' operator is not allowed for source level below 1.7
884 = Redundant specification of type arguments <{0}>
+885 = Potentially leaking resource '{0}': is not closed on all paths
+886 = Potentially leaking resource '{0}': may not be closed at this location
+887 = Leaking resource '{0}': is never closed
+888 = Leaking resource '{0}': is not closed at this location
+889 = Resource '{0}' should be managed by try-with-resource
### ELABORATIONS
## Access restrictions
Index: model/org/eclipse/jdt/core/JavaCore.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java,v
retrieving revision 1.664
diff -u -r1.664 JavaCore.java
--- model/org/eclipse/jdt/core/JavaCore.java 28 Jul 2011 17:07:48 -0000 1.664
+++ model/org/eclipse/jdt/core/JavaCore.java 23 Aug 2011 16:14:13 -0000
@@ -83,6 +83,10 @@
* Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD
* Stephan Herrmann - added COMPILER_PB_UNUSED_OBJECT_ALLOCATION
* Stephan Herrmann - added COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS
+ * Stephan Herrmann - added the following constants:
+ * COMPILER_PB_UNCLOSED_CLOSEABLE,
+ * COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE
+ * COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE
*******************************************************************************/
package org.eclipse.jdt.core;
@@ -1357,6 +1361,52 @@
*/
public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
/**
+ * Compiler option ID: Reporting a resource that is not closed properly.
+ *
When enabled, that compiler will issue an error or a warning if
+ * a local variable holds a value of type AutoCloseable and if
+ * flow analysis shows that the method close() is not invoked locally on that value.
+ *
+ * @since 3.8
+ * @category CompilerOptionID
+ */
+ public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$
+ /**
+ * Compiler option ID: Reporting a resource that may not be closed properly.
+ *
When enabled, that compiler will issue an error or a warning if
+ * a local variable holds a value of type AutoCloseable and if
+ * flow analysis shows that the method close() is
+ * not invoked locally on that value for all execution paths.
+ *
+ * @since 3.8
+ * @category CompilerOptionID
+ */
+ public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
+ /**
+ * Compiler option ID: Reporting a resource that is not managed by try-with-resources.
+ *
When enabled, that compiler will issue an error or a warning if a local variable
+ * holds a value of type AutoCloseable, and if the method close() is
+ * explicitly invoked on that resource, but the resource is not managed by a
+ * try-with-resources block.
+ *
Note that this option is not intended to be surfaced in the UI, as it is intended
+ * only for internal use for computing quick assists / cleanups.
+ *
Specify whether which source level compatibility is used. From 1.4 on, 'assert' is a keyword
* reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
#P org.eclipse.jdt.core.tests.compiler
Index: src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java,v
retrieving revision 1.227
diff -u -r1.227 BatchCompilerTest.java
--- src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java 8 Aug 2011 09:51:23 -0000 1.227
+++ src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java 23 Aug 2011 16:14:25 -0000
@@ -8,9 +8,11 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Benjamin Muskalla - Contribution for bug 239066
- * Stephan Herrmann - Contribution for bug 236385
- * Stephan Herrmann - Contribution for bug 295551
- * Stephan Herrmann - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ * Stephan Herrmann - Contributions for
+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ * bug 295551 - Add option to automatically promote all warnings to errors
+ * bug 185682 - Increment/decrement operators mark local variables as read
+ * bug 349326 - [1.7] new warning for missing try-with-resources
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1816,6 +1818,7 @@
"