Lines 202-207
public class FakedTrackingVariable extends LocalDeclaration {
Link Here
|
202 |
allocation.closeTracker = null; |
202 |
allocation.closeTracker = null; |
203 |
} |
203 |
} |
204 |
} else if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable)) { |
204 |
} else if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable)) { |
|
|
205 |
boolean isWrapper = true; |
205 |
if (allocation.arguments != null && allocation.arguments.length > 0) { |
206 |
if (allocation.arguments != null && allocation.arguments.length > 0) { |
206 |
// find the wrapped resource represented by its tracking var: |
207 |
// find the wrapped resource represented by its tracking var: |
207 |
FakedTrackingVariable innerTracker = findCloseTracker(scope, flowInfo, allocation, allocation.arguments[0]); |
208 |
FakedTrackingVariable innerTracker = findCloseTracker(scope, flowInfo, allocation, allocation.arguments[0]); |
Lines 231-258
public class FakedTrackingVariable extends LocalDeclaration {
Link Here
|
231 |
currentTracker = currentTracker.innerTracker; |
232 |
currentTracker = currentTracker.innerTracker; |
232 |
} |
233 |
} |
233 |
} |
234 |
} |
234 |
return; // keep chaining wrapper |
235 |
return; // keep chaining wrapper (by avoiding to fall through to removeTrackingVar below) |
|
|
236 |
} else { |
237 |
if (!isAnyCloseable(allocation.arguments[0].resolvedType)) { |
238 |
isWrapper = false; // argument is not closeable |
239 |
} |
235 |
} |
240 |
} |
|
|
241 |
} else { |
242 |
isWrapper = false; // no argument |
236 |
} |
243 |
} |
237 |
// remove unnecessary attempts (wrapper has no relevant inner) |
244 |
// successful wrapper detection has exited above, let's see why that failed |
238 |
if (allocation.closeTracker != null) { |
245 |
if (isWrapper) { |
239 |
scope.removeTrackingVar(allocation.closeTracker); |
246 |
// remove unnecessary attempts (wrapper has no relevant inner) |
240 |
allocation.closeTracker = null; |
247 |
if (allocation.closeTracker != null) { |
241 |
} |
248 |
scope.removeTrackingVar(allocation.closeTracker); |
242 |
} else { // regular resource |
249 |
allocation.closeTracker = null; |
243 |
FakedTrackingVariable presetTracker = allocation.closeTracker; |
250 |
} |
244 |
if (presetTracker != null && presetTracker.originalBinding != null) { |
|
|
245 |
int closeStatus = flowInfo.nullStatus(presetTracker.binding); |
246 |
if (closeStatus != FlowInfo.NON_NULL |
247 |
&& closeStatus != FlowInfo.UNKNOWN |
248 |
&& !flowInfo.isDefinitelyNull(presetTracker.originalBinding) |
249 |
&& !(presetTracker.currentAssignment instanceof LocalDeclaration)) |
250 |
allocation.closeTracker.recordErrorLocation(presetTracker.currentAssignment, closeStatus); |
251 |
} else { |
251 |
} else { |
252 |
allocation.closeTracker = new FakedTrackingVariable(scope, allocation); // no local available, closeable is unassigned |
252 |
// allocation does not provide a resource as the first argument -> don't treat as a wrapper |
|
|
253 |
handleRegularResource(scope, flowInfo, allocation); |
253 |
} |
254 |
} |
254 |
flowInfo.markAsDefinitelyNull(allocation.closeTracker.binding); |
255 |
} else { // regular resource |
|
|
256 |
handleRegularResource(scope, flowInfo, allocation); |
257 |
} |
258 |
} |
259 |
|
260 |
private static void handleRegularResource(BlockScope scope, FlowInfo flowInfo, AllocationExpression allocation) { |
261 |
FakedTrackingVariable presetTracker = allocation.closeTracker; |
262 |
if (presetTracker != null && presetTracker.originalBinding != null) { |
263 |
int closeStatus = flowInfo.nullStatus(presetTracker.binding); |
264 |
if (closeStatus != FlowInfo.NON_NULL |
265 |
&& closeStatus != FlowInfo.UNKNOWN |
266 |
&& !flowInfo.isDefinitelyNull(presetTracker.originalBinding) |
267 |
&& !(presetTracker.currentAssignment instanceof LocalDeclaration)) |
268 |
allocation.closeTracker.recordErrorLocation(presetTracker.currentAssignment, closeStatus); |
269 |
} else { |
270 |
allocation.closeTracker = new FakedTrackingVariable(scope, allocation); // no local available, closeable is unassigned |
255 |
} |
271 |
} |
|
|
272 |
flowInfo.markAsDefinitelyNull(allocation.closeTracker.binding); |
256 |
} |
273 |
} |
257 |
|
274 |
|
258 |
/** Find an existing tracking variable for the argument of an allocation for a resource wrapper. */ |
275 |
/** Find an existing tracking variable for the argument of an allocation for a resource wrapper. */ |