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.ast.ASTNode;
 
  14 import net.sourceforge.phpdt.internal.compiler.ast.Reference;
 
  15 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
 
  16 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
 
  17 import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
 
  18 import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding;
 
  21  * Reflects the context of code analysis, keeping track of enclosing try
 
  22  * statements, exception handlers, etc...
 
  24 public class FinallyFlowContext extends FlowContext {
 
  26         Reference finalAssignments[];
 
  28         VariableBinding finalVariables[];
 
  32         public FinallyFlowContext(FlowContext parent, ASTNode associatedNode) {
 
  33                 super(parent, associatedNode);
 
  37          * Given some contextual initialization info (derived from a try block or a
 
  38          * catch block), this code will check that the subroutine context does not
 
  39          * also initialize a final variable potentially set redundantly.
 
  41         public void complainOnRedundantFinalAssignments(FlowInfo flowInfo,
 
  43                 for (int i = 0; i < assignCount; i++) {
 
  44                         VariableBinding variable = finalVariables[i];
 
  48                         boolean complained = false; // remember if have complained on this
 
  50                         if (variable instanceof FieldBinding) {
 
  52                                 if (flowInfo.isPotentiallyAssigned((FieldBinding) variable)) {
 
  54                                         scope.problemReporter()
 
  55                                                         .duplicateInitializationOfBlankFinalField(
 
  56                                                                         (FieldBinding) variable,
 
  60                                 // final local variable
 
  62                                                 .isPotentiallyAssigned((LocalVariableBinding) variable)) {
 
  64                                         scope.problemReporter()
 
  65                                                         .duplicateInitializationOfFinalLocal(
 
  66                                                                         (LocalVariableBinding) variable,
 
  70                         // any reference reported at this level is removed from the parent
 
  72                         // where it could also be reported again
 
  74                                 FlowContext currentContext = parent;
 
  75                                 while (currentContext != null) {
 
  76                                         // if (currentContext.isSubRoutine()) {
 
  78                                                         .removeFinalAssignmentIfAny(finalAssignments[i]);
 
  80                                         currentContext = currentContext.parent;
 
  86         public String individualToString() {
 
  88                 StringBuffer buffer = new StringBuffer("Finally flow context"); //$NON-NLS-1$
 
  90                                 .append("[finalAssignments count -").append(assignCount).append(']'); //$NON-NLS-1$
 
  91                 return buffer.toString();
 
  94         public boolean isSubRoutine() {
 
  98         boolean recordFinalAssignment(VariableBinding binding,
 
  99                         Reference finalAssignment) {
 
 100                 if (assignCount == 0) {
 
 101                         finalAssignments = new Reference[5];
 
 102                         finalVariables = new VariableBinding[5];
 
 104                         if (assignCount == finalAssignments.length)
 
 105                                 System.arraycopy(finalAssignments, 0,
 
 106                                                 (finalAssignments = new Reference[assignCount * 2]), 0,
 
 108                         System.arraycopy(finalVariables, 0,
 
 109                                         (finalVariables = new VariableBinding[assignCount * 2]), 0,
 
 113                 finalAssignments[assignCount] = finalAssignment;
 
 114                 finalVariables[assignCount++] = binding;
 
 118         void removeFinalAssignmentIfAny(Reference reference) {
 
 119                 for (int i = 0; i < assignCount; i++) {
 
 120                         if (finalAssignments[i] == reference) {
 
 121                                 finalAssignments[i] = null;
 
 122                                 finalVariables[i] = null;