suppress "variable not initialized" error for break statements. In switch-case statem...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / SourceTypeBinding.java
index 51d892a..266a332 100644 (file)
@@ -1,18 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v0.5 
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- * 
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package net.sourceforge.phpdt.internal.compiler.lookup;
 
 import java.util.Enumeration;
 import java.util.Hashtable;
 
+import net.sourceforge.phpdt.core.compiler.CharOperation;
 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
 import net.sourceforge.phpdt.internal.compiler.ast.Argument;
 import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement;
@@ -21,10 +22,9 @@ import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
-import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
-import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
+
 
 public class SourceTypeBinding extends ReferenceBinding {
        public ReferenceBinding superclass;
@@ -35,13 +35,14 @@ public class SourceTypeBinding extends ReferenceBinding {
 
        public ClassScope scope;
 
-       // Synthetics are separated into 4 categories: methods, fields, class literals and changed declaring class bindings
+       // Synthetics are separated into 4 categories: methods, super methods, fields, class literals and changed declaring class bindings
        public final static int METHOD = 0;
        public final static int FIELD = 1;
        public final static int CLASS_LITERAL = 2;
        public final static int CHANGED_DECLARING_CLASS = 3;
-       
+
        Hashtable[] synthetics;
+
 protected SourceTypeBinding() {
 }
 public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
@@ -52,7 +53,7 @@ public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassSc
        this.sourceName = scope.referenceContext.name;
        this.scope = scope;
 
-       computeId();
+//     computeId();
 }
 private void addDefaultAbstractMethod(MethodBinding abstractMethod) {
        MethodBinding defaultAbstract = new MethodBinding(
@@ -74,7 +75,7 @@ public void addDefaultAbstractMethods() {
        tagBits |= KnowsDefaultAbstractMethods;
 
        if (isClass() && isAbstract()) {
-               if (fPackage.environment.options.targetJDK >= CompilerOptions.JDK1_2) return; // no longer added for post 1.2 targets
+//             if (fPackage.environment.options.targetJDK >= CompilerOptions.JDK1_2) return; // no longer added for post 1.2 targets
 
                ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
                int lastPosition = 0;
@@ -114,14 +115,14 @@ public FieldBinding addSyntheticField(LocalVariableBinding actualOuterLocalVaria
        if (synthetics[FIELD] == null) {
                synthetics[FIELD] = new Hashtable(5);
        }
-       
+
        FieldBinding synthField = (FieldBinding) synthetics[FIELD].get(actualOuterLocalVariable);
        if (synthField == null) {
                synthField = new SyntheticFieldBinding(
-                       CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name), 
-                       actualOuterLocalVariable.type, 
-                       AccPrivate | AccFinal | AccSynthetic, 
-                       this, 
+                       CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name),
+                       actualOuterLocalVariable.type,
+                       AccPrivate | AccFinal ,//| AccSynthetic,
+                       this,
                        Constant.NotAConstant,
                        synthetics[FIELD].size());
                synthetics[FIELD].put(actualOuterLocalVariable, synthField);
@@ -170,7 +171,7 @@ public FieldBinding addSyntheticField(ReferenceBinding enclosingType) {
                                SyntheticArgumentBinding.EnclosingInstancePrefix,
                                String.valueOf(enclosingType.depth()).toCharArray()),
                        enclosingType,
-                       AccPrivate | AccFinal | AccSynthetic,
+                       AccDefault | AccFinal,// | AccSynthetic,
                        this,
                        Constant.NotAConstant,
                        synthetics[FIELD].size());
@@ -187,7 +188,7 @@ public FieldBinding addSyntheticField(ReferenceBinding enclosingType) {
                                break;
                        }
                }
-       }               
+       }
        return synthField;
 }
 /* Add a new synthetic field for a class literal access.
@@ -209,7 +210,7 @@ public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockSc
                synthField = new SyntheticFieldBinding(
                        ("class$" + synthetics[CLASS_LITERAL].size()).toCharArray(), //$NON-NLS-1$
                        blockScope.getJavaLangClass(),
-                       AccDefault | AccStatic | AccSynthetic,
+                       AccDefault | AccStatic,// | AccSynthetic,
                        this,
                        Constant.NotAConstant,
                        synthetics[CLASS_LITERAL].size());
@@ -226,7 +227,7 @@ public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockSc
                                break;
                        }
                }
-       }               
+       }
        return synthField;
 }
 
@@ -247,10 +248,10 @@ public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScop
                synthField = new SyntheticFieldBinding(
                        "$assertionsDisabled".toCharArray(), //$NON-NLS-1$
                        BooleanBinding,
-                       AccDefault | AccStatic | AccSynthetic | AccFinal,
+                       AccDefault | AccStatic | AccFinal,//| AccSynthetic | AccFinal,
                        this,
                        Constant.NotAConstant,
-                       0);
+                       synthetics[FIELD].size());
                synthetics[FIELD].put("assertionEmulation", synthField); //$NON-NLS-1$
        }
        // ensure there is not already such a field defined by the user
@@ -295,7 +296,7 @@ public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField,
        if (accessors == null) {
                accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this);
                synthetics[METHOD].put(targetField, accessors = new SyntheticAccessMethodBinding[2]);
-               accessors[isReadAccess ? 0 : 1] = accessMethod;         
+               accessors[isReadAccess ? 0 : 1] = accessMethod;
        } else {
                if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) {
                        accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this);
@@ -305,10 +306,11 @@ public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField,
        return accessMethod;
 }
 /* Add a new synthetic access method for access to <targetMethod>.
+ * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
        Answer the new method or the existing method if one already existed.
 */
 
-public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMethod) {
+public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) {
 
        if (synthetics == null) {
                synthetics = new Hashtable[4];
@@ -317,10 +319,17 @@ public SyntheticAccessMethodBinding addSyntheticMethod(MethodBinding targetMetho
                synthetics[METHOD] = new Hashtable(5);
        }
 
-       SyntheticAccessMethodBinding accessMethod = (SyntheticAccessMethodBinding) synthetics[METHOD].get(targetMethod);
-       if (accessMethod == null) {
-               accessMethod = new SyntheticAccessMethodBinding(targetMethod, this);
-               synthetics[METHOD].put(targetMethod, accessMethod);
+       SyntheticAccessMethodBinding accessMethod = null;
+       SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(targetMethod);
+       if (accessors == null) {
+               accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this);
+               synthetics[METHOD].put(targetMethod, accessors = new SyntheticAccessMethodBinding[2]);
+               accessors[isSuperAccess ? 0 : 1] = accessMethod;
+       } else {
+               if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) {
+                       accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this);
+                       accessors[isSuperAccess ? 0 : 1] = accessMethod;
+               }
        }
        return accessMethod;
 }
@@ -341,7 +350,9 @@ void faultInTypesForFieldsAndMethods() {
 // NOTE: the type of each field of a source type is resolved when needed
 
 public FieldBinding[] fields() {
-       
+       if (fields==null) {
+               fields = new FieldBinding[0];
+       }
        try {
                int failed = 0;
                for (int f = 0, max = fields.length; f < max; f++) {
@@ -354,7 +365,7 @@ public FieldBinding[] fields() {
                        int newSize = fields.length - failed;
                        if (newSize == 0)
                                return fields = NoFields;
-       
+
                        FieldBinding[] newFields = new FieldBinding[newSize];
                        for (int i = 0, n = 0, max = fields.length; i < max; i++)
                                if (fields[i] != null)
@@ -375,7 +386,7 @@ public FieldBinding[] fields() {
                }
                if (newFields != null){
                        System.arraycopy(newFields, 0, fields = new FieldBinding[count], 0, count);
-               }                       
+               }
                throw e;
        }
        return fields;
@@ -532,7 +543,7 @@ public MethodBinding[] getMethods(char[] selector) {
                                        }
                                }
                        }
-       
+
                        if (foundProblem || count > 1) {
                                for (int m = methods.length; --m >= 0;) {
                                        MethodBinding method = methods[m];
@@ -563,12 +574,12 @@ public MethodBinding[] getMethods(char[] selector) {
                                                }
                                        }
                                }
-       
+
                                if (failed > 0) {
                                        int newSize = methods.length - failed;
                                        if (newSize == 0)
                                                return methods = NoMethods;
-       
+
                                        MethodBinding[] newMethods = new MethodBinding[newSize];
                                        for (int i = 0, n = 0, max = methods.length; i < max; i++)
                                                if (methods[i] != null)
@@ -604,10 +615,10 @@ public MethodBinding[] getMethods(char[] selector) {
                }
                if (newMethods != null){
                        System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count);
-               }                       
+               }
                modifiers ^= AccUnresolved;
                throw e;
-       }               
+       }
        return NoMethods;
 }
 /* Answer the synthetic field for <actualOuterLocalVariable>
@@ -615,7 +626,7 @@ public MethodBinding[] getMethods(char[] selector) {
 */
 
 public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) {
-       
+
        if (synthetics == null || synthetics[FIELD] == null) return null;
        return (FieldBinding) synthetics[FIELD].get(actualOuterLocalVariable);
 }
@@ -672,7 +683,7 @@ public MethodBinding[] methods() {
        try {
                if ((modifiers & AccUnresolved) == 0)
                        return methods;
-       
+
                int failed = 0;
                for (int m = 0, max = methods.length; m < max; m++) {
                        if (resolveTypesFor(methods[m]) == null) {
@@ -680,7 +691,7 @@ public MethodBinding[] methods() {
                                failed++;
                        }
                }
-       
+
                for (int m = methods.length; --m >= 0;) {
                        MethodBinding method = methods[m];
                        if (method != null) {
@@ -710,7 +721,7 @@ public MethodBinding[] methods() {
                                }
                        }
                }
-       
+
                if (failed > 0) {
                        int newSize = methods.length - failed;
                        if (newSize == 0) {
@@ -723,7 +734,7 @@ public MethodBinding[] methods() {
                                methods = newMethods;
                        }
                }
-       
+
                // handle forward references to potential default abstract methods
                addDefaultAbstractMethods();
        } catch(AbortCompilation e){
@@ -740,10 +751,10 @@ public MethodBinding[] methods() {
                }
                if (newMethods != null){
                        System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count);
-               }                       
+               }
                modifiers ^= AccUnresolved;
                throw e;
-       }               
+       }
        modifiers ^= AccUnresolved;
        return methods;
 }
@@ -872,7 +883,7 @@ public ReferenceBinding[] superInterfaces() {
        return superInterfaces;
 }
 public SyntheticAccessMethodBinding[] syntheticAccessMethods() {
-       
+
        if (synthetics == null || synthetics[METHOD] == null || synthetics[METHOD].size() == 0) return null;
 
        // difficult to compute size up front because of the embedded arrays so assume there is only 1
@@ -880,22 +891,34 @@ public SyntheticAccessMethodBinding[] syntheticAccessMethods() {
        SyntheticAccessMethodBinding[] bindings = new SyntheticAccessMethodBinding[1];
        Enumeration fieldsOrMethods = synthetics[METHOD].keys();
        while (fieldsOrMethods.hasMoreElements()) {
+
                Object fieldOrMethod = fieldsOrMethods.nextElement();
+
                if (fieldOrMethod instanceof MethodBinding) {
-                       if (index + 1 > bindings.length)
-                               System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + 1]), 0, index);
-                       bindings[index++] = (SyntheticAccessMethodBinding) synthetics[METHOD].get(fieldOrMethod);
+
+                       SyntheticAccessMethodBinding[] methodAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(fieldOrMethod);
+                       int numberOfAccessors = 0;
+                       if (methodAccessors[0] != null) numberOfAccessors++;
+                       if (methodAccessors[1] != null) numberOfAccessors++;
+                       if (index + numberOfAccessors > bindings.length)
+                               System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + numberOfAccessors]), 0, index);
+                       if (methodAccessors[0] != null)
+                               bindings[index++] = methodAccessors[0]; // super access
+                       if (methodAccessors[1] != null)
+                               bindings[index++] = methodAccessors[1]; // normal access
+
                } else {
+
                        SyntheticAccessMethodBinding[] fieldAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD].get(fieldOrMethod);
                        int numberOfAccessors = 0;
                        if (fieldAccessors[0] != null) numberOfAccessors++;
                        if (fieldAccessors[1] != null) numberOfAccessors++;
                        if (index + numberOfAccessors > bindings.length)
                                System.arraycopy(bindings, 0, (bindings = new SyntheticAccessMethodBinding[index + numberOfAccessors]), 0, index);
-                       if (fieldAccessors[0] != null) 
-                               bindings[index++] = fieldAccessors[0];
-                       if (fieldAccessors[1] != null) 
-                               bindings[index++] = fieldAccessors[1];
+                       if (fieldAccessors[0] != null)
+                               bindings[index++] = fieldAccessors[0]; // read access
+                       if (fieldAccessors[1] != null)
+                               bindings[index++] = fieldAccessors[1]; // write access
                }
        }
 
@@ -912,7 +935,7 @@ public SyntheticAccessMethodBinding[] syntheticAccessMethods() {
  * Answer the collection of synthetic fields to append into the classfile
  */
 public FieldBinding[] syntheticFields() {
-       
+
        if (synthetics == null) return null;
 
        int fieldSize = synthetics[FIELD] == null ? 0 : synthetics[FIELD].size();
@@ -1018,7 +1041,7 @@ void verifyMethods(MethodVerifier verifier) {
 *      or null if one does not exist.
 */
 
-public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, BlockScope scope, boolean onlyExactMatch) {
+public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
 
        if (synthetics == null || synthetics[FIELD] == null) return null;
        FieldBinding field = (FieldBinding) synthetics[FIELD].get(targetEnclosingType);
@@ -1028,10 +1051,10 @@ public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, Bloc
        // class T { class M{}}
        // class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
        if (!onlyExactMatch){
-               Enumeration enum = synthetics[FIELD].elements();
-               while (enum.hasMoreElements()) {
-                       field = (FieldBinding) enum.nextElement();
-                       if (CharOperation.startsWith(field.name, SyntheticArgumentBinding.EnclosingInstancePrefix)
+               Enumeration e = synthetics[FIELD].elements();
+               while (e.hasMoreElements()) {
+                       field = (FieldBinding) e.nextElement();
+                       if (CharOperation.prefixEquals(SyntheticArgumentBinding.EnclosingInstancePrefix, field.name)
                                && targetEnclosingType.isSuperclassOf((ReferenceBinding) field.type))
                                        return field;
                }