1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.flow;
13 import net.sourceforge.phpdt.internal.compiler.ast.AstNode;
14 import net.sourceforge.phpdt.internal.compiler.ast.NameReference;
15 import net.sourceforge.phpdt.internal.compiler.ast.Reference;
16 import net.sourceforge.phpdt.internal.compiler.codegen.Label;
17 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
18 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
19 import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
20 import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
21 import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding;
24 * Reflects the context of code analysis, keeping track of enclosing
25 * try statements, exception handlers, etc...
27 public class LoopingFlowContext extends SwitchFlowContext {
28 public Label continueLabel;
29 public UnconditionalFlowInfo initsOnContinue = FlowInfo.DeadEnd;
30 Reference finalAssignments[];
31 VariableBinding finalVariables[];
33 Scope associatedScope;
34 public LoopingFlowContext(
36 AstNode associatedNode,
39 Scope associatedScope) {
40 super(parent, associatedNode, breakLabel);
41 this.continueLabel = continueLabel;
42 this.associatedScope = associatedScope;
45 public void complainOnFinalAssignmentsInLoop(
48 for (int i = 0; i < assignCount; i++) {
49 VariableBinding variable;
50 if ((variable = finalVariables[i]) != null) {
51 boolean complained; // remember if have complained on this final assignment
52 if (variable instanceof FieldBinding) {
53 if (complained = flowInfo.isPotentiallyAssigned((FieldBinding) variable)) {
54 scope.problemReporter().duplicateInitializationOfBlankFinalField(
55 (FieldBinding) variable,
56 (NameReference) finalAssignments[i]);
60 flowInfo.isPotentiallyAssigned((LocalVariableBinding) variable)) {
61 scope.problemReporter().duplicateInitializationOfFinalLocal(
62 (LocalVariableBinding) variable,
63 (NameReference) finalAssignments[i]);
66 // any reference reported at this level is removed from the parent context where it
67 // could also be reported again
69 FlowContext context = parent;
70 while (context != null) {
71 context.removeFinalAssignmentIfAny(finalAssignments[i]);
72 context = context.parent;
79 public Label continueLabel() {
83 public String individualToString() {
84 return "Looping flow context"; //$NON-NLS-1$
87 public boolean isContinuable() {
91 public boolean isContinuedTo() {
92 return initsOnContinue != FlowInfo.DeadEnd;
95 public void recordContinueFrom(FlowInfo flowInfo) {
96 if (initsOnContinue == FlowInfo.DeadEnd) {
97 initsOnContinue = flowInfo.copy().unconditionalInits();
99 // ignore if not really reachable (1FKEKRP)
100 if (flowInfo.isFakeReachable())
102 initsOnContinue.mergedWith(flowInfo.unconditionalInits());
106 boolean recordFinalAssignment(
107 VariableBinding binding,
108 Reference finalAssignment) {
109 // do not consider variables which are defined inside this loop
110 if (binding instanceof LocalVariableBinding) {
111 Scope scope = ((LocalVariableBinding) binding).declaringScope;
112 while ((scope = scope.parent) != null) {
113 if (scope == associatedScope)
117 if (assignCount == 0) {
118 finalAssignments = new Reference[5];
119 finalVariables = new VariableBinding[5];
121 if (assignCount == finalAssignments.length)
125 (finalAssignments = new Reference[assignCount * 2]),
131 (finalVariables = new VariableBinding[assignCount * 2]),
135 finalAssignments[assignCount] = finalAssignment;
136 finalVariables[assignCount++] = binding;
140 void removeFinalAssignmentIfAny(Reference reference) {
141 for (int i = 0; i < assignCount; i++) {
142 if (finalAssignments[i] == reference) {
143 finalAssignments[i] = null;
144 finalVariables[i] = null;