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 203975 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]
patch v0.9.9
Bug_349326_v0.9.9.patch (text/plain), 158.02 KB, created by
Stephan Herrmann
on 2011-09-25 17:15:38 EDT
(
hide
)
Description:
patch v0.9.9
Filename:
MIME Type:
Creator:
Stephan Herrmann
Created:
2011-09-25 17:15:38 EDT
Size:
158.02 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >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 25 Sep 2011 21:11:31 -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 25 Sep 2011 21:11:32 -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 25 Sep 2011 21:11:32 -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,27 @@ > 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 >+ local.closeTracker.recordErrorLocation(this, flowInfo.nullStatus(trackerBinding)); >+ } >+ } >+ if (FakedTrackingVariable.isAutoCloseable(this.expression.resolvedType)) { >+ // 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 25 Sep 2011 21:11:32 -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; > >@@ -32,10 +33,12 @@ > int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED; > for (int i = 0, max = this.statements.length; i < max; i++) { > Statement stat = this.statements[i]; >- if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = stat.complainIfUnreachable(flowInfo, flowContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > 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/ConditionalExpression.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java,v >retrieving revision 1.101 >diff -u -r1.101 ConditionalExpression.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java 12 Aug 2011 20:48:20 -0000 1.101 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java 25 Sep 2011 21:11:34 -0000 >@@ -12,6 +12,7 @@ > * bug 292478 - Report potentially null across variable assignment > * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself > * bug 354554 - [null] conditional with redundant condition yields weak error message >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -65,7 +66,7 @@ > trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); > } > if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel); >+ this.valueIfTrue.complainIfUnreachable(trueFlowInfo, flowContext, currentScope, initialComplaintLevel, false); > } > } > this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo); >@@ -78,7 +79,7 @@ > falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); > } > if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel); >+ this.valueIfFalse.complainIfUnreachable(falseFlowInfo, flowContext, currentScope, initialComplaintLevel, true); > } > } > this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo); >Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java,v >retrieving revision 1.115 >diff -u -r1.115 ConstructorDeclaration.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 25 Apr 2011 22:51:18 -0000 1.115 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 25 Sep 2011 21:11:35 -0000 >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for Bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance >+ * Stephan Herrmann - Contributions for >+ * bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -151,7 +153,7 @@ > int complaintLevel = (nonStaticFieldInfoReachMode & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE; > for (int i = 0, count = this.statements.length; i < count; i++) { > Statement stat = this.statements[i]; >- if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = stat.complainIfUnreachable(flowInfo, constructorContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo); > } > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java,v >retrieving revision 1.26 >diff -u -r1.26 EmptyStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java 7 Mar 2009 01:08:07 -0000 1.26 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java 25 Sep 2011 21:11:35 -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; > >@@ -29,12 +30,12 @@ > } > > // Report an error if necessary >- public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int complaintLevel) { >+ public int complainIfUnreachable(FlowInfo flowInfo, FlowContext flowContext, BlockScope scope, int complaintLevel, boolean endOfBlock) { > // before 1.4, empty statements are tolerated anywhere > if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) { > return complaintLevel; > } >- return super.complainIfUnreachable(flowInfo, scope, complaintLevel); >+ return super.complainIfUnreachable(flowInfo, flowContext, scope, complaintLevel, endOfBlock); > } > > public void generateCode(BlockScope currentScope, CodeStream codeStream){ >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,166 @@ >+/******************************************************************************* >+ * 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 java.util.HashMap; >+import java.util.Iterator; >+import java.util.Map; >+import java.util.Map.Entry; >+ >+import org.eclipse.jdt.core.compiler.CharOperation; >+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.Binding; >+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.Scope; >+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.ProblemReporter; >+ >+/** >+ * 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 close() is invoked from a nested method (inside a local type) >+ * report remaining problems only as potential. >+ */ >+ public boolean closedInNestedMethod; >+ >+ MethodScope methodScope; // designates the method declaring this variable >+ >+ public LocalVariableBinding originalBinding; // the real local being tracked >+ >+ HashMap recordedLocations; // initially null, ASTNode -> Integer >+ >+ 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; >+ } >+ >+ /** if 'invocationSite' is a call to close() that has a registered tracking variable, answer that variable's binding. */ >+ public static LocalVariableBinding getTrackerForCloseCall(ASTNode invocationSite) { >+ if (invocationSite instanceof MessageSend) { >+ MessageSend send = (MessageSend) invocationSite; >+ if (CharOperation.equals(TypeConstants.CLOSE, send.selector) && send.receiver instanceof SingleNameReference) { >+ Binding receiverBinding = ((SingleNameReference)send.receiver).binding; >+ if (receiverBinding instanceof LocalVariableBinding) { >+ FakedTrackingVariable trackingVariable = ((LocalVariableBinding)receiverBinding).closeTracker; >+ if (trackingVariable != null) >+ return trackingVariable.binding; >+ } >+ } >+ } >+ 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|TypeIds.BitCloseable); >+ } >+ >+ public void recordErrorLocation(ASTNode location, int nullStatus) { >+ if (this.recordedLocations == null) >+ this.recordedLocations = new HashMap(); >+ this.recordedLocations.put(location, new Integer(nullStatus)); >+ } >+ >+ public boolean reportRecordedErrors(Scope scope) { >+ boolean hasReported = false; >+ if (this.recordedLocations != null) { >+ Iterator locations = this.recordedLocations.entrySet().iterator(); >+ while (locations.hasNext()) { >+ Map.Entry entry = (Entry) locations.next(); >+ reportError(scope.problemReporter(), (ASTNode)entry.getKey(), ((Integer)entry.getValue()).intValue()); >+ hasReported = true; >+ } >+ } >+ return hasReported; >+ } >+ >+ public void reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) { >+ if (nullStatus == FlowInfo.NULL) { >+ if (this.closedInNestedMethod) >+ problemReporter.potentiallyUnclosedCloseable(this, location); >+ else >+ problemReporter.unclosedCloseable(this, location); >+ } else if (nullStatus == FlowInfo.POTENTIALLY_NULL) { >+ problemReporter.potentiallyUnclosedCloseable(this, location); >+ } >+ } >+} >Index: compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java,v >retrieving revision 1.71 >diff -u -r1.71 ForStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java 5 Mar 2011 17:18:43 -0000 1.71 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java 25 Sep 2011 21:11:37 -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; > >@@ -138,7 +140,7 @@ > actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); > } > } >- if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) { >+ if (this.action.complainIfUnreachable(actionInfo, flowContext, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) { > actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalInits(); > } > >Index: compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java,v >retrieving revision 1.65 >diff -u -r1.65 ForeachStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java 5 Mar 2011 17:18:43 -0000 1.65 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java 25 Sep 2011 21:11:39 -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; > >@@ -99,7 +100,7 @@ > if (!(this.action == null || (this.action.isEmptyBlock() > && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) { > >- if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) { >+ if (this.action.complainIfUnreachable(actionInfo, flowContext, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) { > actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy(); > } > >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 25 Sep 2011 21:11:39 -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; > >@@ -89,7 +91,7 @@ > this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo); > if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) { > if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, initialComplaintLevel); >+ this.thenStatement.complainIfUnreachable(thenFlowInfo, flowContext, currentScope, initialComplaintLevel, false); > } else { > // its a known coding pattern which should be tolerated by dead code analysis > // according to isKnowDeadCodePattern() >@@ -115,7 +117,7 @@ > this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo); > if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) { > if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, initialComplaintLevel); >+ this.elseStatement.complainIfUnreachable(elseFlowInfo, flowContext, currentScope, initialComplaintLevel, false); > } else { > // its a known coding pattern which should be tolerated by dead code analysis > // according to isKnowDeadCodePattern() >@@ -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 25 Sep 2011 21:11:39 -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 25 Sep 2011 21:11:40 -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 25 Sep 2011 21:11:41 -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; > >@@ -100,7 +101,7 @@ > int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE; > for (int i = 0, count = this.statements.length; i < count; i++) { > Statement stat = this.statements[i]; >- if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = stat.complainIfUnreachable(flowInfo, methodContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo); > } > } >@@ -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 25 Sep 2011 21:11:41 -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 25 Sep 2011 21:11:43 -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,12 @@ > 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: >+ currentScope.removeTrackingVar(trackingVariable); >+ } > } > this.initStateIndex = > currentScope.methodScope().recordInitializationStates(flowInfo); >@@ -104,6 +112,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/Statement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java,v >retrieving revision 1.53 >diff -u -r1.53 Statement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java 28 Jul 2011 17:07:04 -0000 1.53 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java 25 Sep 2011 21:11:43 -0000 >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 335093 - [compiler][null] minimal hook for future null annotation support >+ * Stephan Herrmann - Contributions for >+ * 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; > >@@ -70,18 +72,22 @@ > > // Report an error if necessary (if even more unreachable than previously reported > // complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error) >-public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel) { >+public int complainIfUnreachable(FlowInfo flowInfo, FlowContext flowContext, BlockScope scope, int previousComplaintLevel, boolean endOfBlock) { > if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) { > if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0) > this.bits &= ~ASTNode.IsReachable; > if (flowInfo == FlowInfo.DEAD_END) { > if (previousComplaintLevel < COMPLAINED_UNREACHABLE) { > scope.problemReporter().unreachableCode(this); >+ if (endOfBlock) >+ scope.checkUnclosedCloseables(flowInfo, flowContext, null); > } > return COMPLAINED_UNREACHABLE; > } else { > if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) { > scope.problemReporter().fakeReachable(this); >+ if (endOfBlock) >+ scope.checkUnclosedCloseables(flowInfo, flowContext, null); > } > return COMPLAINED_FAKE_REACHABLE; > } >Index: compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java,v >retrieving revision 1.82 >diff -u -r1.82 SwitchStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java 1 Sep 2011 18:42:40 -0000 1.82 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java 25 Sep 2011 21:11:44 -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; > >@@ -99,7 +101,7 @@ > } else { > fallThroughState = FALLTHROUGH; // reset below if needed > } >- if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = statement.complainIfUnreachable(caseInits, flowContext, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > caseInits = statement.analyseCode(this.scope, switchContext, caseInits); > if (caseInits == FlowInfo.DEAD_END) { > fallThroughState = ESCAPING; >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 25 Sep 2011 21:11:45 -0000 >@@ -7,7 +7,9 @@ > * > * 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; > >@@ -124,8 +126,14 @@ > 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) { >+ // this was false alarm, we don't need to track the resource >+ this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker); >+ resourceBinding.closeTracker = null; >+ } >+ 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 +258,14 @@ > 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) { >+ // this was false alarm, we don't need to track the resource >+ this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker); >+ resourceBinding.closeTracker = null; >+ } >+ 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 >Index: compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java,v >retrieving revision 1.68 >diff -u -r1.68 WhileStatement.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java 5 Mar 2011 17:18:43 -0000 1.68 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java 25 Sep 2011 21:11:47 -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; > >@@ -113,7 +115,7 @@ > currentScope.methodScope().recordInitializationStates( > condInfo.initsWhenTrue()); > >- if (this.action.complainIfUnreachable(actionInfo, currentScope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) { >+ if (this.action.complainIfUnreachable(actionInfo, flowContext, currentScope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) { > actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo); > } > >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 25 Sep 2011 21:11:52 -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 25 Sep 2011 21:11:56 -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,10 @@ > 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; >+ // bits 8-10 reserved for https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342 >+ public static final int UnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit11; >+ public static final int PotentiallyUnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit12; >+ public static final int ExplicitlyClosedAutoCloseable = IrritantSet.GROUP2 | ASTNode.Bit13; > > // Severity level for handlers > /** >@@ -376,8 +385,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 +561,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 +730,9 @@ > OPTION_ReportUnusedTypeArgumentsForMethodInvocation, > OPTION_ReportUnusedWarningToken, > OPTION_ReportVarargsArgumentNeedCast, >+ OPTION_ReportUnclosedCloseable, >+ OPTION_ReportPotentiallyUnclosedCloseable, >+ OPTION_ReportExplicitlyClosedAutoCloseable, > }; > return result; > } >@@ -784,10 +803,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 +864,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 +1005,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 +1438,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 +1656,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 25 Sep 2011 21:11:58 -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.137 >diff -u -r1.137 BinaryTypeBinding.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 9 Sep 2011 14:13:17 -0000 1.137 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 25 Sep 2011 21:11:59 -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; > >@@ -972,6 +973,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) >@@ -1140,8 +1147,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 >@@ -1151,8 +1164,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 25 Sep 2011 21:12:02 -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,140 @@ > } > } > } >+ >+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(3); >+ this.trackingVariables.add(fakedTrackingVariable); >+ MethodScope outerMethodScope = outerMostMethodScope(); >+ return outerMethodScope.analysisIndex + (outerMethodScope.trackVarCount++); >+ >+} >+/** When no longer interested in this tracking variable remove it. */ >+public void removeTrackingVar(FakedTrackingVariable trackingVariable) { >+ if (this.trackingVariables != null) >+ if (this.trackingVariables.remove(trackingVariable)) >+ return; >+ if (this.parent instanceof BlockScope) >+ ((BlockScope)this.parent).removeTrackingVar(trackingVariable); >+} >+/** >+ * At the end of a block check the closing-status of all tracked closeables that are declared in this block. >+ * Also invoked when entering unreachable code. >+ */ >+public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location) { >+ if (this.trackingVariables == null) return; >+ if (location != null && flowInfo.reachMode() != 0) return; >+ for (int i=0; i<this.trackingVariables.size(); i++) { >+ FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i); >+ if (location != null && trackingVar.originalBinding != null && flowInfo.isDefinitelyNull(trackingVar.originalBinding)) >+ continue; // reporting against a specific location, resource is null at this flow, don't complain >+ int status = getNullStatusAggressively(trackingVar.binding, flowInfo); >+ if (status == FlowInfo.NULL) { >+ // definitely unclosed: highest priority >+ reportResourceLeak(trackingVar, location, status); >+ if (location == null) { >+ // definitely done with this trackingVar, remove it >+ this.trackingVariables.remove(trackingVar); >+ i--; // ... but don't disturb the enclosing loop. >+ } >+ continue; >+ } >+ if (location == null) // at end of block an not definitely unclosed >+ { >+ // problems at specific locations: medium priority >+ if (trackingVar.reportRecordedErrors(this)) // ... report previously recorded errors >+ continue; >+ } >+ if (status == FlowInfo.POTENTIALLY_NULL) { >+ // potentially unclosed: lower priority >+ reportResourceLeak(trackingVar, location, status); >+ } else if (status == FlowInfo.NON_NULL) { >+ // properly closed but not managed by t-w-r: lowest priority >+ if (environment().globalOptions.complianceLevel >= ClassFileConstants.JDK1_7) >+ problemReporter().explicitlyClosedAutoCloseable(trackingVar); >+ } >+ } >+} >+private void reportResourceLeak(FakedTrackingVariable trackingVar, ASTNode location, int nullStatus) { >+ if (location != null) >+ trackingVar.recordErrorLocation(location, nullStatus); >+ else >+ trackingVar.reportError(problemReporter(), null, nullStatus); >+} >+ >+/** >+ * 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); >+} >+ >+/** >+ * Get the null status looking even into unreachable flows >+ * @param local >+ * @param flowInfo >+ * @return one of the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}. >+ */ >+private int getNullStatusAggressively(LocalVariableBinding local, FlowInfo flowInfo) { >+ int reachMode = flowInfo.reachMode(); >+ int status = 0; >+ try { >+ // unreachable flowInfo is too shy in reporting null-issues, temporarily forget reachability: >+ if (reachMode != FlowInfo.REACHABLE) >+ flowInfo.tagBits &= ~FlowInfo.UNREACHABLE; >+ status = flowInfo.nullStatus(local); >+ } finally { >+ // reset >+ flowInfo.tagBits |= reachMode; >+ } >+ // at this point some combinations are not useful so flatten to a single bit: >+ 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/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 25 Sep 2011 21:12:03 -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 25 Sep 2011 21:12:05 -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 25 Sep 2011 21:12:05 -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 = 0; >+ > 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.121 >diff -u -r1.121 ParameterizedTypeBinding.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 23 Aug 2011 17:05:22 -0000 1.121 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 25 Sep 2011 21:12: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; > >@@ -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) > */ >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 25 Sep 2011 21:12: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; > >@@ -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.144 >diff -u -r1.144 ReferenceBinding.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 31 Aug 2011 20:19:50 -0000 1.144 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 25 Sep 2011 21:12: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) { >@@ -392,6 +397,10 @@ > case 'i' : > if (CharOperation.equals(packageName, TypeConstants.IO)) { > switch (typeName[0]) { >+ case 'C' : >+ if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2])) >+ this.typeBits |= TypeIds.BitCloseable; // don't assign id, only typeBit (for analysis of resource leaks) >+ return; > case 'E' : > if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2])) > this.id = TypeIds.T_JavaIoExternalizable; >@@ -438,8 +447,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])) >@@ -937,6 +948,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 25 Sep 2011 21:12:13 -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.53 >diff -u -r1.53 TypeConstants.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java 31 Aug 2011 20:19:50 -0000 1.53 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java 25 Sep 2011 21:12:13 -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; > >@@ -123,6 +124,7 @@ > char[][] JAVA_LANG_ANNOTATION_ELEMENTTYPE = {JAVA, LANG, ANNOTATION, "ElementType".toCharArray()}; //$NON-NLS-1$ > char[][] JAVA_LANG_REFLECT_FIELD = new char[][] {JAVA, LANG, REFLECT, "Field".toCharArray()}; //$NON-NLS-1$ > char[][] JAVA_LANG_REFLECT_METHOD = new char[][] {JAVA, LANG, REFLECT, "Method".toCharArray()}; //$NON-NLS-1$ >+ char[][] JAVA_IO_CLOSEABLE = new char[][] { JAVA, IO, "Closeable".toCharArray()};//$NON-NLS-1$ > char[][] JAVA_IO_OBJECTSTREAMEXCEPTION = new char[][] { JAVA, IO, "ObjectStreamException".toCharArray()};//$NON-NLS-1$ > char[][] JAVA_IO_EXTERNALIZABLE = {JAVA, IO, "Externalizable".toCharArray()}; //$NON-NLS-1$ > char[][] JAVA_IO_IOEXCEPTION = new char[][] { JAVA, IO, "IOException".toCharArray()};//$NON-NLS-1$ >@@ -151,6 +153,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.40 >diff -u -r1.40 TypeIds.java >--- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java 31 Aug 2011 20:19:50 -0000 1.40 >+++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java 25 Sep 2011 21:12:13 -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; > >@@ -182,4 +183,15 @@ > 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; >+ /** >+ * Marks all sub-types of java.io.Closeable. >+ * @see ReferenceBinding#hasTypeBit(int) >+ */ >+ final int BitCloseable = 2; > } >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 25 Sep 2011 21:12:14 -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 25 Sep 2011 21:12:14 -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 25 Sep 2011 21:12:16 -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.440 >diff -u -r1.440 ProblemReporter.java >--- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 31 Aug 2011 20:19:51 -0000 1.440 >+++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 25 Sep 2011 21:12:28 -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 : >@@ -7931,4 +7945,49 @@ > 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); >+ } >+} >+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); >+ } >+} >+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 25 Sep 2011 21:12:29 -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 = Potential resource leak: '{0}' may not be closed >+886 = Potential resource leak: '{0}' may not be closed at this location >+887 = Resource leak: '{0}' is never closed >+888 = Resource leak: '{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.665 >diff -u -r1.665 JavaCore.java >--- model/org/eclipse/jdt/core/JavaCore.java 1 Sep 2011 18:42:40 -0000 1.665 >+++ model/org/eclipse/jdt/core/JavaCore.java 25 Sep 2011 21:12:40 -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 25 Sep 2011 21:13:02 -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 25 Sep 2011 21:13:07 -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/FlowAnalysisTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java,v >retrieving revision 1.47 >diff -u -r1.47 FlowAnalysisTest.java >--- src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 4 Mar 2011 12:41:15 -0000 1.47 >+++ src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 25 Sep 2011 21:13:11 -0000 >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * 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; > >@@ -2360,6 +2362,52 @@ > "The local variable i may not have been initialized\n" + > "----------\n"); > } >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// variant < 1.7 using Closeable: not closed >+public void testCloseable1() { >+ 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); // not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file); // not closed\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n"); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// variant < 1.7 using Closeable: resource is closed, cannot suggest try-with-resources < 1.7 >+public void testCloseable2() { >+ 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); // not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ ""); >+} > public static Class testClass() { > return FlowAnalysisTest.class; > } >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 25 Sep 2011 21:13:17 -0000 >@@ -7,18 +7,20 @@ > * > * 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; > public class TryWithResourcesStatementTest extends AbstractRegressionTest { > > static { >-// TESTS_NAMES = new String[] { "test055", "test055a" }; >+// TESTS_NAMES = new String[] { "test056u" }; > // TESTS_NUMBERS = new int[] { 50 }; > // TESTS_RANGE = new int[] { 11, -1 }; > } >@@ -485,12 +487,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" + >+ "Resource leak: '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 22)\n" + >+ "5. WARNING in X.java (at line 22)\n" + > " class WeirdException extends Throwable {}\n" + > " ^^^^^^^^^^^^^^\n" + > "The serializable class WeirdException does not declare a static final serialVersionUID field of type long\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" + >+ "Resource leak: '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,1184 @@ > }, > "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" + >+ "Resource leak: '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 not protected by t-w-r nor regular try-finally >+public void test056a() { >+ 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" + >+ " 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" + >+ "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 >+// 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" + >+ "Potential resource leak: 'fileReader2' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: \'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" + >+ "Resource leak: \'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" + >+ "Resource leak: '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" + >+ " fileReader = null;\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" + >+ "Resource leak: \'fileReader\' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// an AutoCloseable local is re-assigned after null-assigned >+public void test056g2() { >+ 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 = null;\n" + >+ " fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here >+ " 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 = null;\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'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" + >+ "Potential resource leak: 'fileReader' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " FileReader localReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Resource leak: '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" + >+ "Resource leak: '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" + >+ "Potential resource leak: 'fileReader' may not be 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 test056i2() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ 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); // properly closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " while (true) {\n" + >+ " fileReader.close();\n" + >+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + >+ " loopReader.close();\n" + >+ " 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 18)\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\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" + >+ "Potential resource leak: 'fileReader' may not be closed\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 test056jconditional() { >+ 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(boolean b) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " synchronized (b ? this : new X()) {\n" + >+ " new ReadDelegator(fileReader);\n" + >+ " }\n" + >+ " }\n" + >+ " class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\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" + >+ "Resource leak: '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" + >+ "Resource leak: '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" + // the effect of this close() call might be spoiled by exception in fileReader.close() above, but we ignore exception exits in the analysis >+ " }\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" + >+ "Potential resource leak: 'r2' may not be closed\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" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// closed in dead code >+public void test056q() { >+ 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" + >+ " if (2*2 == 4)\n" + >+ " return;\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 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: \'fileReader\' is never closed\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 10)\n" + >+ " if (2*2 == 4)\n" + >+ " ^^^^^^^^\n" + >+ "Comparing identical expressions\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 12)\n" + >+ " fileReader.close();\n" + >+ " ^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// closed in dead code >+public void test056r() { >+ 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); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, 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 fr = new FileReader(file);\n" + >+ " Object b = null;\n" + >+ " fr.close();\n" + >+ " if (b != null) {\n" + >+ " fr = new FileReader(file);\n" + >+ " return;\n" + >+ " } else {\n" + >+ " System.out.print(42);\n" + >+ " }\n" + >+ " return; // Should not complain about fr\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" + >+ " if (b != null) {\n" + >+ " fr = new FileReader(file);\n" + >+ " return;\n" + >+ " } else {\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 13)\n" + >+ " } else {\n" + >+ " System.out.print(42);\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation >+public void test056s() { >+ 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" + >+ " try (FileReader fileReader = new FileReader(file);) {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader = new FileReader(file); // debug here\n" + >+ " fileReader.read(in);\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 10)\n" + >+ " fileReader = new FileReader(file); // debug here\n" + >+ " ^^^^^^^^^^\n" + >+ "The resource fileReader of a try-with-resources statement cannot be assigned\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource is closed, dead code follows >+public void test056t() { >+ 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_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo31() throws IOException {\n" + >+ " FileReader reader = new FileReader(\"file\"); //warning\n" + >+ " if (reader != null) {\n" + >+ " reader.close();\n" + >+ " } else {\n" + >+ " // nop\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo31();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " } else {\n" + >+ " // nop\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource is reassigned within t-w-r with different resource >+// disabled due to Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis >+public void _test056u() { >+ 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_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo() throws Exception {\n" + >+ " FileReader reader1 = new FileReader(\"file1\");\n" + >+ " FileReader reader2 = new FileReader(\"file2\");\n" + >+ " reader2 = reader1;// warning 1\n" + >+ " try (FileReader reader3 = new FileReader(\"file3\")) {\n" + >+ " int ch;\n" + >+ " while ((ch = reader2.read()) != -1) {\n" + >+ " System.out.println(ch);\n" + >+ " reader1.read();\n" + >+ " }\n" + >+ " reader2 = reader1;// warning 2\n" + >+ " reader2 = reader1;// warning 3\n" + >+ " } finally {\n" + >+ " if (reader2 != null) {\n" + >+ " reader2.close();\n" + >+ " } else {\n" + >+ " System.out.println();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader1 = new FileReader(\"file1\");\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: \'reader1\' is never closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " reader2 = reader1;// warning 1\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'reader2\' is not closed at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 13)\n" + >+ " reader2 = reader1;// warning 2\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'reader2\' is not closed at this location\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 14)\n" + >+ " reader2 = reader1;// warning 3\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'reader2\' is not closed at this location\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