1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.flow;
13 import net.sourceforge.phpdt.internal.compiler.codegen.Label;
14 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
15 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
16 import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
17 import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
18 import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding;
19 import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
20 import net.sourceforge.phpeclipse.internal.compiler.ast.Reference;
23 * Reflects the context of code analysis, keeping track of enclosing
24 * try statements, exception handlers, etc...
26 public class LoopingFlowContext extends SwitchFlowContext {
28 public Label continueLabel;
29 public UnconditionalFlowInfo initsOnContinue = FlowInfo.DEAD_END;
30 Reference finalAssignments[];
31 VariableBinding finalVariables[];
33 Scope associatedScope;
35 public LoopingFlowContext(
37 ASTNode associatedNode,
40 Scope associatedScope) {
41 super(parent, associatedNode, breakLabel);
42 this.continueLabel = continueLabel;
43 this.associatedScope = associatedScope;
46 public void complainOnFinalAssignmentsInLoop(
49 for (int i = 0; i < assignCount; i++) {
50 VariableBinding variable = finalVariables[i];
51 if (variable == null) continue;
52 boolean complained = false; // remember if have complained on this final assignment
53 if (variable instanceof FieldBinding) {
54 if (flowInfo.isPotentiallyAssigned((FieldBinding) variable)) {
56 scope.problemReporter().duplicateInitializationOfBlankFinalField(
57 (FieldBinding) variable,
61 if (flowInfo.isPotentiallyAssigned((LocalVariableBinding) variable)) {
63 scope.problemReporter().duplicateInitializationOfFinalLocal(
64 (LocalVariableBinding) variable,
68 // any reference reported at this level is removed from the parent context where it
69 // could also be reported again
71 FlowContext context = parent;
72 while (context != null) {
73 context.removeFinalAssignmentIfAny(finalAssignments[i]);
74 context = context.parent;
80 public Label continueLabel() {
84 public String individualToString() {
85 StringBuffer buffer = new StringBuffer("Looping flow context"); //$NON-NLS-1$
86 buffer.append("[initsOnBreak -").append(initsOnBreak.toString()).append(']'); //$NON-NLS-1$
87 buffer.append("[initsOnContinue -").append(initsOnContinue.toString()).append(']'); //$NON-NLS-1$
88 return buffer.toString();
91 public boolean isContinuable() {
95 public boolean isContinuedTo() {
96 return initsOnContinue != FlowInfo.DEAD_END;
99 public void recordContinueFrom(FlowInfo flowInfo) {
101 if (!flowInfo.isReachable()) return;
102 if (initsOnContinue == FlowInfo.DEAD_END) {
103 initsOnContinue = flowInfo.copy().unconditionalInits();
105 initsOnContinue = initsOnContinue.mergedWith(flowInfo.unconditionalInits());
109 boolean recordFinalAssignment(
110 VariableBinding binding,
111 Reference finalAssignment) {
112 // do not consider variables which are defined inside this loop
113 if (binding instanceof LocalVariableBinding) {
114 Scope scope = ((LocalVariableBinding) binding).declaringScope;
115 while ((scope = scope.parent) != null) {
116 if (scope == associatedScope)
120 if (assignCount == 0) {
121 finalAssignments = new Reference[5];
122 finalVariables = new VariableBinding[5];
124 if (assignCount == finalAssignments.length)
128 (finalAssignments = new Reference[assignCount * 2]),
134 (finalVariables = new VariableBinding[assignCount * 2]),
138 finalAssignments[assignCount] = finalAssignment;
139 finalVariables[assignCount++] = binding;
143 void removeFinalAssignmentIfAny(Reference reference) {
144 for (int i = 0; i < assignCount; i++) {
145 if (finalAssignments[i] == reference) {
146 finalAssignments[i] = null;
147 finalVariables[i] = null;