Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 202016 Details for
Bug 349326
[1.7] new warning for missing try-with-resources
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
updated patch for HEAD
patch349326.txt (text/plain), 135.26 KB, created by
Ayushman Jain
on 2011-08-23 12:22:37 EDT
(
hide
)
Description:
updated patch for HEAD
Filename:
MIME Type:
Creator:
Ayushman Jain
Created:
2011-08-23 12:22:37 EDT
Size:
135.26 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: batch/org/eclipse/jdt/internal/compiler/batch/messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties,v >retrieving revision 1.994 >diff -u -r1.994 messages.properties >--- batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 16 Aug 2011 19:12:00 -0000 1.994 >+++ batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 23 Aug 2011 16:13:58 -0000 >@@ -15,7 +15,7 @@ > #Format: compiler.name = word1 word2 word3 > compiler.name = Eclipse Compiler for Java(TM) > #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)] >-compiler.version = 0.C06, 3.8.0 M2 >+compiler.version = 0.C07, 3.8.0 M2 > compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved. > > ### progress >Index: buildnotes_jdt-core.html >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/buildnotes_jdt-core.html,v >retrieving revision 1.7889 >diff -u -r1.7889 buildnotes_jdt-core.html >--- buildnotes_jdt-core.html 23 Aug 2011 07:00:14 -0000 1.7889 >+++ buildnotes_jdt-core.html 23 Aug 2011 16:13:58 -0000 >@@ -42,11 +42,24 @@ > </td> > </tr> > </table> >+<a name="v_C07"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - %date% - 3.8.0 M2 >+<br>Project org.eclipse.jdt.core v_C07 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C07">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353640">353640</a> >+AIOOBE in ParameterizedTypeBinding.substitute >+ > <a name="v_C06"></a> > <hr><h1> > Eclipse Platform Build Notes<br> > Java development tools core</h1> >-Eclipse SDK 3.8.0 - August 23, 2011 - 3.8.0 M2 >+Eclipse SDK 3.8.0 - August 23, 2011 > <br>Project org.eclipse.jdt.core v_C06 > (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C06">cvs</a>). > <h2>What's new in this drop</h2> >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<this.trackingVariables.size(); i++) { >+ FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i); >+ if (trackingVar.hasReportedProblem) >+ continue; >+ if (trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding)) >+ continue; // resource is null at this flow, don't complain >+ int status = FlowContext.getNullStatusAfter(trackingVar.binding, flowInfo, flowContext); >+ if (status == FlowInfo.NULL) { >+ if (trackingVar.closedInNestedMethod) >+ problemReporter().potentiallyUnclosedCloseable(trackingVar, location); >+ else >+ problemReporter().unclosedCloseable(trackingVar, location); >+ } else if (status == FlowInfo.POTENTIALLY_NULL) { >+ problemReporter().potentiallyUnclosedCloseable(trackingVar, location); >+ } else if (status == FlowInfo.NON_NULL) { >+ if (environment().globalOptions.complianceLevel >= 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<this.trackingVariables.size(); i++) { >+ FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i); >+ if (flowInfo.nullStatus(trackingVar.binding) == FlowInfo.UNKNOWN) >+ continue; >+ moreTrackVars.add(trackingVar); >+ } >+ } >+ if (this.parent instanceof BlockScope) >+ ((BlockScope) this.parent).getTrackVars(moreTrackVars, flowInfo); >+} >+ >+/** >+ * If one branch of an if-else closes any AutoCloseable resource, and if the same >+ * resource is known to be null on the other branch mark it as closed, too, >+ * so that merging both branches indicates that the resource is always closed. >+ * Example: >+ * FileReader fr1 = null; >+ * try {\n" + >+ * fr1 = new FileReader(someFile);" + >+ * fr1.read(buf);\n" + >+ * } finally {\n" + >+ * if (fr1 != null)\n" + >+ * try {\n" + >+ * fr1.close();\n" + >+ * } catch (IOException e) { >+ * // do nothing >+ * } >+ * // after this if statement fr1 is definitely not leaked >+ * } >+ */ >+public void correlateTrackingVarsIfElse(FlowInfo thenFlowInfo, FlowInfo elseFlowInfo) { >+ if (this.trackingVariables != null) { >+ for (int i=0; i<this.trackingVariables.size(); i++) { >+ FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i); >+ if ( thenFlowInfo.isDefinitelyNonNull(trackingVar.binding) // closed in then branch >+ && elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding)) // null in else branch >+ { >+ elseFlowInfo.markAsDefinitelyNonNull(trackingVar.binding); // -> 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 <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - 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 <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - 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 <stephan@cs.tu-berlin.de> - Contribution for bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - 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 <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+# Stephan Herrmann <stephan@cs.tu-berlin.de> - 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. >+ * <p>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 <code>close()</code> is not invoked locally on that value. >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"warning"</code></dd> >+ * </dl> >+ * @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. >+ * <p>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 <code>close()</code> is >+ * not invoked locally on that value for all execution paths. >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"ignore"</code></dd> >+ * </dl> >+ * @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. >+ * <p>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 <code>close()</code> is >+ * explicitly invoked on that resource, but the resource is not managed by a >+ * try-with-resources block. >+ * <p>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. >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"ignore"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$ >+ /** > * Compiler option ID: Setting Source Compatibility Mode. > * <p>Specify whether which source level compatibility is used. From 1.4 on, <code>'assert'</code> 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 <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - 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 @@ > " <option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" + >@@ -1857,6 +1860,7 @@ > " <option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" + >@@ -1872,6 +1876,7 @@ > " <option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + >Index: src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java,v >retrieving revision 1.43 >diff -u -r1.43 CompilerInvocationTests.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java 23 Aug 2011 06:03:50 -0000 1.43 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java 23 Aug 2011 16:14:25 -0000 >@@ -8,7 +8,9 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Benjamin Muskalla - Contribution for bug 239066 >- * Stephan Herrmann - Contribution for bug 236385 >+ * Stephan Herrmann - Contributions for >+ * bug 236385: [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -440,6 +442,7 @@ > expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED); > expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED); > expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED); >+ expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); > expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); > expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); >@@ -765,6 +768,8 @@ > expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); >@@ -828,6 +833,8 @@ > expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); > expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT)); > expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); >+ expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >@@ -1108,6 +1115,7 @@ > expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP); > expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP); > expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP); >+ expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE)); > expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP); > expectedProblemAttributes.put("ExternalProblemFixable", SKIP); > expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP); >@@ -1433,6 +1441,8 @@ > expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP); > expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT)); > expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE)); > expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE)); > expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP); > expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP); >@@ -1496,6 +1506,8 @@ > expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION)); > expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING)); > expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING)); >+ expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE)); >+ expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE)); > expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP); > expectedProblemAttributes.put("UndefinedConstructor", SKIP); > expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP); >Index: src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java,v >retrieving revision 1.4 >diff -u -r1.4 TryWithResourcesStatementTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java 18 Aug 2011 17:07:34 -0000 1.4 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java 23 Aug 2011 16:14:25 -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.core.tests.compiler.regression; > > import java.util.Map; > >+import org.eclipse.jdt.core.JavaCore; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > > import junit.framework.Test; >@@ -485,7 +487,12 @@ > " ^^\n" + > "Dead code\n" + > "----------\n" + >- "3. ERROR in X.java (at line 5)\n" + >+ "3. WARNING in X.java (at line 5)\n" + >+ " Y why = new Y();\n" + >+ " ^^^\n" + >+ "Leaking resource 'why': is never closed\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 5)\n" + > " Y why = new Y();\n" + > " ^^^^^^^\n" + > "Unhandled exception type WeirdException\n" + >@@ -558,12 +565,17 @@ > " ^^\n" + > "Dead code\n" + > "----------\n" + >- "3. ERROR in X.java (at line 5)\n" + >+ "3. WARNING in X.java (at line 5)\n" + >+ " Y why = new Y();\n" + >+ " ^^^\n" + >+ "Leaking resource 'why': is never closed\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 5)\n" + > " Y why = new Y();\n" + > " ^^^^^^^\n" + > "Unhandled exception type WeirdException\n" + > "----------\n" + >- "4. WARNING in X.java (at line 20)\n" + >+ "5. WARNING in X.java (at line 20)\n" + > " class WeirdException extends Throwable {}\n" + > " ^^^^^^^^^^^^^^\n" + > "The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + >@@ -3380,6 +3392,823 @@ > }, > "Done"); > } >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable without ever closing it. >+public void test056() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler >+// " char[] in = new char[50];\n" + >+// " fileReader.read(in);\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Leaking resource 'fileReader': is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable and closes it but exception may occur earlier. >+public void test056a() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ioex) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potentially leaking resource 'fileReader': is not closed on all paths\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable and closes it properly in a finally block >+public void test056b() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " try {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ioex) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable properly within try-with-resources. >+public void test056c() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " try (FileReader fileReader = new FileReader(file)) {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ioex) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses two AutoCloseables (testing independent analysis) >+// - one closeable may be unclosed at a conditional return >+// - the other is only conditionally closed >+public void test056d() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean flag1, boolean flag2) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " char[] in = new char[50];\n" + >+ " FileReader fileReader1 = new FileReader(file);\n" + >+ " fileReader1.read(in);\n" + >+ " FileReader fileReader2 = new FileReader(file);\n" + >+ " fileReader2.read(in);\n" + >+ " if (flag1) {\n" + >+ " fileReader2.close();\n" + >+ " return;\n" + >+ " } else if (flag2) {\n" + >+ " fileReader2.close();\n" + >+ " }\n" + >+ " fileReader1.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(false, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 10)\n" + >+ " FileReader fileReader2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Potentially leaking resource 'fileReader2': is not closed on all paths\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Leaking resource \'fileReader1\': is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+//Bug 349326 - [1.7] new warning for missing try-with-resources >+//a method uses two AutoCloseables (testing independent analysis) >+//- one closeable may be unclosed at a conditional return >+//- the other is only conditionally closed >+public void test056d_suppress() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean flag1, boolean flag2) throws IOException {\n" + >+ " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + >+ " char[] in = new char[50];\n" + >+ " FileReader fileReader1 = new FileReader(file);\n" + >+ " fileReader1.read(in);\n" + >+ " @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" + >+ " fileReader2.read(in);\n" + >+ " if (flag1) {\n" + >+ " fileReader2.close();\n" + >+ " return; // not suppressed\n" + >+ " } else if (flag2) {\n" + >+ " fileReader2.close();\n" + >+ " }\n" + >+ " fileReader1.close();\n" + >+ " }\n" + >+ " @SuppressWarnings(\"resource\") // useful suppress\n" + >+ " void bar() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(false, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 6)\n" + >+ " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + >+ " ^^^^^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"resource\")\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " return; // not suppressed\n" + >+ " ^^^^^^^\n" + >+ "Leaking resource \'fileReader1\': is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// one method returns an AutoCleasble, a second method uses this object without ever closing it. >+public void test056e() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " FileReader getReader(String filename) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " return fileReader;\n" + // don't complain here, pass responsibility to caller >+ " }\n" + >+ " void foo() throws IOException {\n" + >+ " FileReader reader = getReader(\"somefile\");\n" + >+ " char[] in = new char[50];\n" + >+ " reader.read(in);\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " FileReader reader = getReader(\"somefile\");\n" + >+ " ^^^^^^\n" + >+ "Leaking resource 'reader': is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method explicitly closes its AutoCloseable rather than using t-w-r >+public void test056f() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = null;\n" + >+ " try {\n" + >+ " fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = null;\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource \'fileReader\' should be managed by try-with-resource\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// an AutoCloseable local is re-assigned >+public void test056g() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader = new FileReader(file);\n" + >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Leaking resource \'fileReader\': is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// two AutoCloseables at different nesting levels (anonymous local type) >+public void test056h() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " final File file = new File(\"somefile\");\n" + >+ " final FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " new Runnable() {\n public void run() {\n" + >+ " try {\n" + >+ " fileReader.close();\n" + >+ " FileReader localReader = new FileReader(file);\n" + >+ " } catch (IOException ex) { /* nop */ }\n" + >+ " }}.run();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 7)\n" + >+ " final FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potentially leaking resource 'fileReader': is not closed on all paths\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " FileReader localReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Leaking resource 'localReader': is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// three AutoCloseables in different blocks of the same method >+public void test056i() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean f1, boolean f2) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " if (f1) {\n" + >+ " FileReader fileReader = new FileReader(file); // err: not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " while (true) {\n" + >+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + >+ " loopReader.close();" + >+ " break;\n" + >+ " }\n" + >+ " } else {\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " if (f2)\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(true, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " FileReader fileReader = new FileReader(file); // err: not closed\n" + >+ " ^^^^^^^^^^\n" + >+ "Leaking resource 'fileReader': is never closed\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 16)\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " ^^^^^^^^^^\n" + >+ "Potentially leaking resource 'fileReader': is not closed on all paths\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable without closing it locally but passing as arg to another method >+public void test056j() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " read(fileReader);\n" + >+ " }\n" + >+ " void read(FileReader reader) { }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potentially leaking resource 'fileReader': is not closed on all paths\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// many locals, some are AutoCloseable. >+// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3, >+// doing so would create false positives. >+public void test056k() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" + >+ " i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" + >+ " i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" + >+ " i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" + >+ " i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader ra1 = null, ra2 = null;\n" + >+ " try {\n" + >+ " ra1 = new FileReader(file);\n" + >+ " ra2 = new FileReader(file);\n" + >+ " FileReader ra3 = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " ra1.read(in);\n" + >+ " ra2.read(in);\n" + >+ " ra3.close();\n" + >+ " } finally {\n" + >+ " ra1.close();\n" + >+ " }\n" + >+ " int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits >+ " FileReader rb1 = null, rb2 = null;\n" + >+ " try {\n" + >+ " rb1 = new FileReader(file);\n" + >+ " rb2 = new FileReader(file);\n" + >+ " FileReader rb3 = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " rb1.read(in);\n" + >+ " rb2.read(in);\n" + >+ " rb3.close();\n" + >+ " } finally {\n" + >+ " rb1.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 12)\n" + >+ " FileReader ra1 = null, ra2 = null;\n" + >+ " ^^^\n" + >+ "Resource \'ra1\' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 15)\n" + >+ " ra2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Leaking resource 'ra2': is never closed\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 16)\n" + >+ " FileReader ra3 = new FileReader(file);\n" + >+ " ^^^\n" + >+ "Resource \'ra3\' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 25)\n" + >+ " FileReader rb1 = null, rb2 = null;\n" + >+ " ^^^\n" + >+ "Resource \'rb1\' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "5. ERROR in X.java (at line 28)\n" + >+ " rb2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Leaking resource 'rb2': is never closed\n" + >+ "----------\n" + >+ "6. ERROR in X.java (at line 29)\n" + >+ " FileReader rb3 = new FileReader(file);\n" + >+ " ^^^\n" + >+ "Resource \'rb3\' should be managed by try-with-resource\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// various non-problems >+public void test056l() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " X(FileReader r0) {}\n" + // don't complain against argument >+ " FileReader getReader() { return null; }\n" + >+ " void foo(FileReader r1) throws IOException {\n" + >+ " FileReader fileReader = getReader();\n" + >+ " if (fileReader == null)\n" + >+ " return;\n" + // don't complain, resource is actually null >+ " FileReader r3 = getReader();\n" + >+ " if (r3 == null)\n" + >+ " r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null >+ " try {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " r1.read(in);\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " r3.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + >+ " new X(r2).foo(new FileReader(new File(\"notthere\")));\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " FileReader fileReader = getReader();\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource \'fileReader\' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 11)\n" + >+ " FileReader r3 = getReader();\n" + >+ " ^^\n" + >+ "Resource \'r3\' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 24)\n" + >+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + >+ " ^^\n" + >+ "Potentially leaking resource 'r2': is not closed on all paths\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// nested try with early exit >+public void test056m() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() {\n" + >+ " File file = new File(\"somefile\");" + >+ " try {\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " try {\n" + >+ " char[] in = new char[50];\n" + >+ " if (fileReader.read(in)==0)\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " } catch (IOException e) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// nested try should not interfere with earlier analysis. >+public void test056n() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "public class X {\n" + >+ " void foo(File someFile, char[] buf) throws IOException {\n" + >+ " FileReader fr1 = new FileReader(someFile);\n" + >+ " try {\n" + >+ " fr1.read(buf);\n" + >+ " } finally {\n" + >+ " fr1.close();\n" + >+ " }\n" + >+ " try {\n" + >+ " FileReader fr3 = new FileReader(someFile);\n" + >+ " try {\n" + >+ " } finally {\n" + >+ " fr3.close();\n" + >+ " }\n" + >+ " } catch (IOException e) {\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo(new File(\"missing\"), new char[100]);\n" + >+ " } catch (FileNotFoundException e) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// if close is guarded by null check this should still be recognized as definitely closed >+public void test056o() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "public class X {\n" + >+ " void foo(File someFile, char[] buf) throws IOException {\n" + >+ " FileReader fr1 = null;\n" + >+ " try {\n" + >+ " fr1 = new FileReader(someFile);" + >+ " fr1.read(buf);\n" + >+ " } finally {\n" + >+ " if (fr1 != null)\n" + >+ " try {\n" + >+ " fr1.close();\n" + >+ " } catch (IOException e) { /*do nothing*/ }\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo(new File(\"missing\"), new char[100]);\n" + >+ " } catch (FileNotFoundException e) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable without ever closing it, type from a type variable >+public void test056p() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.Reader;\n" + >+ "import java.io.IOException;\n" + >+ "public abstract class X <T extends Reader> {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " T fileReader = newReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " abstract T newReader(File file) throws IOException;\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X<FileReader>() {\n" + >+ " FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" + >+ " }.foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " T fileReader = newReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Leaking resource 'fileReader': is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} > public static Class testClass() { > return TryWithResourcesStatementTest.class; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 349326
:
198503
|
199192
|
199216
|
199235
|
199358
|
199378
|
199385
|
199402
|
199435
|
199443
|
199812
|
201450
|
202016
|
202189
|
202721
|
203866
|
203961
|
203975
|
204041
|
204066
|
204108