Lines 13-18
Link Here
|
13 |
import org.eclipse.jdt.internal.compiler.ast.ASTNode; |
13 |
import org.eclipse.jdt.internal.compiler.ast.ASTNode; |
14 |
import org.eclipse.jdt.internal.compiler.ast.Expression; |
14 |
import org.eclipse.jdt.internal.compiler.ast.Expression; |
15 |
import org.eclipse.jdt.internal.compiler.ast.Reference; |
15 |
import org.eclipse.jdt.internal.compiler.ast.Reference; |
|
|
16 |
import org.eclipse.jdt.internal.compiler.ast.TryStatement; |
16 |
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; |
17 |
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; |
17 |
import org.eclipse.jdt.internal.compiler.lookup.BlockScope; |
18 |
import org.eclipse.jdt.internal.compiler.lookup.BlockScope; |
18 |
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; |
19 |
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; |
Lines 32-37
Link Here
|
32 |
private LoopingFlowContext innerFlowContexts[] = null; |
33 |
private LoopingFlowContext innerFlowContexts[] = null; |
33 |
private UnconditionalFlowInfo innerFlowInfos[] = null; |
34 |
private UnconditionalFlowInfo innerFlowInfos[] = null; |
34 |
private int innerFlowContextsNb = 0; |
35 |
private int innerFlowContextsNb = 0; |
|
|
36 |
private FlowContext breakTargetContexts[] = null; |
37 |
private UnconditionalFlowInfo breakTargetsInfo[] = null; |
38 |
public int breakTargetsNb = 0; |
35 |
|
39 |
|
36 |
Reference finalAssignments[]; |
40 |
Reference finalAssignments[]; |
37 |
VariableBinding finalVariables[]; |
41 |
VariableBinding finalVariables[]; |
Lines 101-109
Link Here
|
101 |
/** |
105 |
/** |
102 |
* Perform deferred checks relative to the null status of local variables. |
106 |
* Perform deferred checks relative to the null status of local variables. |
103 |
* @param scope the scope to which this context is associated |
107 |
* @param scope the scope to which this context is associated |
104 |
* @param flowInfo the flow info against which checks must be performed |
108 |
* @param callerFlowInfo the flow info against which checks must be performed |
105 |
*/ |
109 |
*/ |
106 |
public void complainOnDeferredNullChecks(BlockScope scope, FlowInfo flowInfo) { |
110 |
public void complainOnDeferredNullChecks(BlockScope scope, FlowInfo callerFlowInfo) { |
107 |
for (int i = 0 ; i < this.innerFlowContextsNb ; i++) { |
111 |
for (int i = 0 ; i < this.innerFlowContextsNb ; i++) { |
108 |
this.upstreamNullFlowInfo. |
112 |
this.upstreamNullFlowInfo. |
109 |
addPotentialNullInfoFrom( |
113 |
addPotentialNullInfoFrom( |
Lines 111-119
Link Here
|
111 |
addPotentialNullInfoFrom(this.innerFlowInfos[i]); |
115 |
addPotentialNullInfoFrom(this.innerFlowInfos[i]); |
112 |
} |
116 |
} |
113 |
this.innerFlowContextsNb = 0; |
117 |
this.innerFlowContextsNb = 0; |
114 |
flowInfo = this.upstreamNullFlowInfo. |
118 |
UnconditionalFlowInfo flowInfo = this.upstreamNullFlowInfo. |
115 |
addPotentialNullInfoFrom( |
119 |
addPotentialNullInfoFrom(callerFlowInfo.unconditionalInitsWithoutSideEffect()); |
116 |
flowInfo.unconditionalInitsWithoutSideEffect()); |
|
|
117 |
if (this.deferNullDiagnostic) { |
120 |
if (this.deferNullDiagnostic) { |
118 |
// check only immutable null checks on innermost looping context |
121 |
// check only immutable null checks on innermost looping context |
119 |
for (int i = 0; i < this.nullCount; i++) { |
122 |
for (int i = 0; i < this.nullCount; i++) { |
Lines 247-252
Link Here
|
247 |
} |
250 |
} |
248 |
} |
251 |
} |
249 |
} |
252 |
} |
|
|
253 |
// propagate breaks - see BreakStatement#analyseCode |
254 |
for (int i = 0; i < this.breakTargetsNb; i++) { |
255 |
UnconditionalFlowInfo breakFlowInfo = this.breakTargetsInfo[i].addPotentialNullInfoFrom(flowInfo); |
256 |
FlowContext traversedContext = this; |
257 |
do { |
258 |
if (traversedContext instanceof InsideSubRoutineFlowContext) { |
259 |
ASTNode node = traversedContext.associatedNode; |
260 |
if (node instanceof TryStatement) { |
261 |
TryStatement tryStatement = (TryStatement) node; |
262 |
breakFlowInfo.addInitializationsFrom(tryStatement.subRoutineInits); |
263 |
} |
264 |
} else if (traversedContext == this.breakTargetContexts[i]) { |
265 |
traversedContext.recordBreakFrom(breakFlowInfo); |
266 |
break; |
267 |
} else if (traversedContext != this && traversedContext.preemptNullDiagnostic) { |
268 |
traversedContext.recordBreakFrom(breakFlowInfo, this.breakTargetContexts[i]); |
269 |
break; |
270 |
} |
271 |
} while ((traversedContext = traversedContext.parent) != null); |
272 |
} |
250 |
} |
273 |
} |
251 |
|
274 |
|
252 |
public BranchLabel continueLabel() { |
275 |
public BranchLabel continueLabel() { |
Lines 270-275
Link Here
|
270 |
return initsOnContinue != FlowInfo.DEAD_END; |
293 |
return initsOnContinue != FlowInfo.DEAD_END; |
271 |
} |
294 |
} |
272 |
|
295 |
|
|
|
296 |
public void recordBreakFrom(UnconditionalFlowInfo flowInfo, FlowContext targetContext) { |
297 |
int current; |
298 |
if ((current = this.breakTargetsNb++) == 0) { |
299 |
this.breakTargetsInfo = new UnconditionalFlowInfo[2]; |
300 |
this.breakTargetContexts = new FlowContext[2]; |
301 |
} else if (current == this.breakTargetsInfo.length) { |
302 |
System.arraycopy(this.breakTargetsInfo, 0, this.breakTargetsInfo = new UnconditionalFlowInfo[current + 2], 0, current); |
303 |
System.arraycopy(this.breakTargetContexts, 0, this.breakTargetContexts = new FlowContext[current + 2], 0, current); |
304 |
} |
305 |
this.breakTargetsInfo[current] = flowInfo; |
306 |
this.breakTargetContexts[current] = targetContext; |
307 |
} |
308 |
|
273 |
public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) { |
309 |
public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) { |
274 |
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { |
310 |
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { |
275 |
if ((initsOnContinue.tagBits & FlowInfo.UNREACHABLE) == 0) { |
311 |
if ((initsOnContinue.tagBits & FlowInfo.UNREACHABLE) == 0) { |