totally new file layout
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / lookup / SourceTypeBinding.java
diff --git a/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
deleted file mode 100644 (file)
index e791f1e..0000000
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 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-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.lookup;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
-import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
-
-public class SourceTypeBinding extends ReferenceBinding {
-       public ReferenceBinding superclass;
-       public ReferenceBinding[] superInterfaces;
-       public FieldBinding[] fields;
-       public MethodBinding[] methods;
-       public ReferenceBinding[] memberTypes;
-
-       public ClassScope scope;
-
-       // Synthetics are separated into 4 categories: methods, super methods, fields, class literals and changed declaring type bindings
-       public final static int METHOD_EMUL = 0;
-       public final static int FIELD_EMUL = 1;
-       public final static int CLASS_LITERAL_EMUL = 2;
-       public final static int RECEIVER_TYPE_EMUL = 3;
-       
-       Hashtable[] synthetics;
-       
-public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
-       this.compoundName = compoundName;
-       this.fPackage = fPackage;
-       this.fileName = scope.referenceCompilationUnit().getFileName();
-       this.modifiers = scope.referenceContext.modifiers;
-       this.sourceName = scope.referenceContext.name;
-       this.scope = scope;
-
-       // expect the fields & methods to be initialized correctly later
-       this.fields = NoFields;
-       this.methods = NoMethods;
-
-       computeId();
-}
-private void addDefaultAbstractMethod(MethodBinding abstractMethod) {
-       MethodBinding defaultAbstract = new MethodBinding(
-               abstractMethod.modifiers | AccDefaultAbstract,
-               abstractMethod.selector,
-               abstractMethod.returnType,
-               abstractMethod.parameters,
-               abstractMethod.thrownExceptions,
-               this);
-
-       MethodBinding[] temp = new MethodBinding[methods.length + 1];
-       System.arraycopy(methods, 0, temp, 0, methods.length);
-       temp[methods.length] = defaultAbstract;
-       methods = temp;
-}
-public void addDefaultAbstractMethods() {
-       if ((tagBits & KnowsDefaultAbstractMethods) != 0) return;
-
-       tagBits |= KnowsDefaultAbstractMethods;
-
-       if (isClass() && isAbstract()) {
-               if (fPackage.environment.options.targetJDK >= ClassFileConstants.JDK1_2) return; // no longer added for post 1.2 targets
-
-               ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
-               int lastPosition = 0;
-               interfacesToVisit[lastPosition] = superInterfaces();
-
-               for (int i = 0; i <= lastPosition; i++) {
-                       ReferenceBinding[] interfaces = interfacesToVisit[i];
-                       for (int j = 0, length = interfaces.length; j < length; j++) {
-                               ReferenceBinding superType = interfaces[j];
-                               if (superType.isValidBinding()) {
-                                       MethodBinding[] superMethods = superType.methods();
-                                       for (int m = superMethods.length; --m >= 0;) {
-                                               MethodBinding method = superMethods[m];
-                                               if (!implementsMethod(method))
-                                                       addDefaultAbstractMethod(method);
-                                       }
-
-                                       ReferenceBinding[] itsInterfaces = superType.superInterfaces();
-                                       if (itsInterfaces != NoSuperInterfaces) {
-                                               if (++lastPosition == interfacesToVisit.length)
-                                                       System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
-                                               interfacesToVisit[lastPosition] = itsInterfaces;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-/* Add a new synthetic field for <actualOuterLocalVariable>.
-*      Answer the new field or the existing field if one already existed.
-*/
-
-public FieldBinding addSyntheticField(LocalVariableBinding actualOuterLocalVariable) {
-       if (synthetics == null) {
-               synthetics = new Hashtable[4];
-       }
-       if (synthetics[FIELD_EMUL] == null) {
-               synthetics[FIELD_EMUL] = new Hashtable(5);
-       }
-       
-       FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get(actualOuterLocalVariable);
-       if (synthField == null) {
-               synthField = new SyntheticFieldBinding(
-                       CharOperation.concat(SyntheticArgumentBinding.OuterLocalPrefix, actualOuterLocalVariable.name), 
-                       actualOuterLocalVariable.type, 
-                       AccPrivate | AccFinal | AccSynthetic, 
-                       this, 
-                       Constant.NotAConstant,
-                       synthetics[FIELD_EMUL].size());
-               synthetics[FIELD_EMUL].put(actualOuterLocalVariable, synthField);
-       }
-
-       // ensure there is not already such a field defined by the user
-       boolean needRecheck;
-       int index = 1;
-       do {
-               needRecheck = false;
-               FieldBinding existingField;
-               if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
-                       TypeDeclaration typeDecl = scope.referenceContext;
-                       for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
-                               FieldDeclaration fieldDecl = typeDecl.fields[i];
-                               if (fieldDecl.binding == existingField) {
-                                       synthField.name = CharOperation.concat(
-                                               SyntheticArgumentBinding.OuterLocalPrefix,
-                                               actualOuterLocalVariable.name,
-                                               ("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
-                                       needRecheck = true;
-                                       break;
-                               }
-                       }
-               }
-       } while (needRecheck);
-       return synthField;
-}
-/* Add a new synthetic field for <enclosingType>.
-*      Answer the new field or the existing field if one already existed.
-*/
-
-public FieldBinding addSyntheticField(ReferenceBinding enclosingType) {
-
-       if (synthetics == null) {
-               synthetics = new Hashtable[4];
-       }
-       if (synthetics[FIELD_EMUL] == null) {
-               synthetics[FIELD_EMUL] = new Hashtable(5);
-       }
-
-       FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get(enclosingType);
-       if (synthField == null) {
-               synthField = new SyntheticFieldBinding(
-                       CharOperation.concat(
-                               SyntheticArgumentBinding.EnclosingInstancePrefix,
-                               String.valueOf(enclosingType.depth()).toCharArray()),
-                       enclosingType,
-                       AccDefault | AccFinal | AccSynthetic,
-                       this,
-                       Constant.NotAConstant,
-                       synthetics[FIELD_EMUL].size());
-               synthetics[FIELD_EMUL].put(enclosingType, synthField);
-       }
-       // ensure there is not already such a field defined by the user
-       FieldBinding existingField;
-       if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
-               TypeDeclaration typeDecl = scope.referenceContext;
-               for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
-                       FieldDeclaration fieldDecl = typeDecl.fields[i];
-                       if (fieldDecl.binding == existingField) {
-                               scope.problemReporter().duplicateFieldInType(this, fieldDecl);
-                               break;
-                       }
-               }
-       }               
-       return synthField;
-}
-/* Add a new synthetic field for a class literal access.
-*      Answer the new field or the existing field if one already existed.
-*/
-
-public FieldBinding addSyntheticField(TypeBinding targetType, BlockScope blockScope) {
-
-       if (synthetics == null) {
-               synthetics = new Hashtable[4];
-       }
-       if (synthetics[CLASS_LITERAL_EMUL] == null) {
-               synthetics[CLASS_LITERAL_EMUL] = new Hashtable(5);
-       }
-
-       // use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.
-       FieldBinding synthField = (FieldBinding) synthetics[CLASS_LITERAL_EMUL].get(targetType);
-       if (synthField == null) {
-               synthField = new SyntheticFieldBinding(
-                       ("class$" + synthetics[CLASS_LITERAL_EMUL].size()).toCharArray(), //$NON-NLS-1$
-                       blockScope.getJavaLangClass(),
-                       AccDefault | AccStatic | AccSynthetic,
-                       this,
-                       Constant.NotAConstant,
-                       synthetics[CLASS_LITERAL_EMUL].size());
-               synthetics[CLASS_LITERAL_EMUL].put(targetType, synthField);
-       }
-       // ensure there is not already such a field defined by the user
-       FieldBinding existingField;
-       if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
-               TypeDeclaration typeDecl = blockScope.referenceType();
-               for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
-                       FieldDeclaration fieldDecl = typeDecl.fields[i];
-                       if (fieldDecl.binding == existingField) {
-                               blockScope.problemReporter().duplicateFieldInType(this, fieldDecl);
-                               break;
-                       }
-               }
-       }               
-       return synthField;
-}
-
-/* Add a new synthetic field for the emulation of the assert statement.
-*      Answer the new field or the existing field if one already existed.
-*/
-public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScope blockScope) {
-
-       if (synthetics == null) {
-               synthetics = new Hashtable[4];
-       }
-       if (synthetics[FIELD_EMUL] == null) {
-               synthetics[FIELD_EMUL] = new Hashtable(5);
-       }
-
-       FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get("assertionEmulation"); //$NON-NLS-1$
-       if (synthField == null) {
-               synthField = new SyntheticFieldBinding(
-                       "$assertionsDisabled".toCharArray(), //$NON-NLS-1$
-                       BooleanBinding,
-                       AccDefault | AccStatic | AccSynthetic | AccFinal,
-                       this,
-                       Constant.NotAConstant,
-                       synthetics[FIELD_EMUL].size());
-               synthetics[FIELD_EMUL].put("assertionEmulation", synthField); //$NON-NLS-1$
-       }
-       // ensure there is not already such a field defined by the user
-       // ensure there is not already such a field defined by the user
-       boolean needRecheck;
-       int index = 0;
-       do {
-               needRecheck = false;
-               FieldBinding existingField;
-               if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
-                       TypeDeclaration typeDecl = scope.referenceContext;
-                       for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
-                               FieldDeclaration fieldDecl = typeDecl.fields[i];
-                               if (fieldDecl.binding == existingField) {
-                                       synthField.name = CharOperation.concat(
-                                               "$assertionsDisabled".toCharArray(), //$NON-NLS-1$
-                                               ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
-                                       needRecheck = true;
-                                       break;
-                               }
-                       }
-               }
-       } while (needRecheck);
-       return synthField;
-}
-
-/* Add a new synthetic access method for read/write access to <targetField>.
-       Answer the new method or the existing method if one already existed.
-*/
-
-public SyntheticAccessMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess) {
-
-       if (synthetics == null) {
-               synthetics = new Hashtable[4];
-       }
-       if (synthetics[METHOD_EMUL] == null) {
-               synthetics[METHOD_EMUL] = new Hashtable(5);
-       }
-
-       SyntheticAccessMethodBinding accessMethod = null;
-       SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].get(targetField);
-       if (accessors == null) {
-               accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this);
-               synthetics[METHOD_EMUL].put(targetField, accessors = new SyntheticAccessMethodBinding[2]);
-               accessors[isReadAccess ? 0 : 1] = accessMethod;         
-       } else {
-               if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) {
-                       accessMethod = new SyntheticAccessMethodBinding(targetField, isReadAccess, this);
-                       accessors[isReadAccess ? 0 : 1] = accessMethod;
-               }
-       }
-       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, boolean isSuperAccess) {
-
-       if (synthetics == null) {
-               synthetics = new Hashtable[4];
-       }
-       if (synthetics[METHOD_EMUL] == null) {
-               synthetics[METHOD_EMUL] = new Hashtable(5);
-       }
-
-       SyntheticAccessMethodBinding accessMethod = null;
-       SyntheticAccessMethodBinding[] accessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].get(targetMethod);
-       if (accessors == null) {
-               accessMethod = new SyntheticAccessMethodBinding(targetMethod, isSuperAccess, this);
-               synthetics[METHOD_EMUL].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;
-}
-
-public FieldBinding[] availableFields() {
-       return fields();
-}
-public MethodBinding[] availableMethods() {
-       return methods();
-}
-void faultInTypesForFieldsAndMethods() {
-       fields();
-       methods();
-
-       for (int i = 0, length = memberTypes.length; i < length; i++)
-               ((SourceTypeBinding) memberTypes[i]).faultInTypesForFieldsAndMethods();
-}
-// NOTE: the type of each field of a source type is resolved when needed
-
-public FieldBinding[] fields() {
-       
-       try {
-               int failed = 0;
-               for (int f = 0, max = fields.length; f < max; f++) {
-                       if (resolveTypeFor(fields[f]) == null) {
-                               fields[f] = null;
-                               failed++;
-                       }
-               }
-               if (failed > 0) {
-                       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)
-                                       newFields[n++] = fields[i];
-                       fields = newFields;
-               }
-       } catch(AbortCompilation e){
-               // ensure null fields are removed
-               FieldBinding[] newFields = null;
-               int count = 0;
-               for (int i = 0, max = fields.length; i < max; i++){
-                       FieldBinding field = fields[i];
-                       if (field == null && newFields == null){
-                               System.arraycopy(fields, 0, newFields = new FieldBinding[max], 0, i);
-                       } else if (newFields != null && field != null) {
-                               newFields[count++] = field;
-                       }
-               }
-               if (newFields != null){
-                       System.arraycopy(newFields, 0, fields = new FieldBinding[count], 0, count);
-               }                       
-               throw e;
-       }
-       return fields;
-}
-public MethodBinding[] getDefaultAbstractMethods() {
-       int count = 0;
-       for (int i = methods.length; --i >= 0;)
-               if (methods[i].isDefaultAbstract())
-                       count++;
-       if (count == 0) return NoMethods;
-
-       MethodBinding[] result = new MethodBinding[count];
-       count = 0;
-       for (int i = methods.length; --i >= 0;)
-               if (methods[i].isDefaultAbstract())
-                       result[count++] = methods[i];
-       return result;
-}
-// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
-
-public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
-       int argCount = argumentTypes.length;
-
-       if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
-               nextMethod : for (int m = methods.length; --m >= 0;) {
-                       MethodBinding method = methods[m];
-                       if (method.selector == ConstructorDeclaration.ConstantPoolName && method.parameters.length == argCount) {
-                               TypeBinding[] toMatch = method.parameters;
-                               for (int p = 0; p < argCount; p++)
-                                       if (toMatch[p] != argumentTypes[p])
-                                               continue nextMethod;
-                               return method;
-                       }
-               }
-       } else {
-               MethodBinding[] constructors = getMethods(ConstructorDeclaration.ConstantPoolName); // takes care of duplicates & default abstract methods
-               nextConstructor : for (int c = constructors.length; --c >= 0;) {
-                       MethodBinding constructor = constructors[c];
-                       TypeBinding[] toMatch = constructor.parameters;
-                       if (toMatch.length == argCount) {
-                               for (int p = 0; p < argCount; p++)
-                                       if (toMatch[p] != argumentTypes[p])
-                                               continue nextConstructor;
-                               return constructor;
-                       }
-               }
-       }
-       return null;
-}
-// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
-// searches up the hierarchy as long as no potential (but not exact) match was found.
-
-public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) {
-       int argCount = argumentTypes.length;
-       int selectorLength = selector.length;
-       boolean foundNothing = true;
-
-       if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
-               nextMethod : for (int m = methods.length; --m >= 0;) {
-                       MethodBinding method = methods[m];
-                       if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) {
-                               foundNothing = false; // inner type lookups must know that a method with this name exists
-                               if (method.parameters.length == argCount) {
-                                       TypeBinding[] toMatch = method.parameters;
-                                       for (int p = 0; p < argCount; p++)
-                                               if (toMatch[p] != argumentTypes[p])
-                                                       continue nextMethod;
-                                       return method;
-                               }
-                       }
-               }
-       } else {
-               MethodBinding[] matchingMethods = getMethods(selector); // takes care of duplicates & default abstract methods
-               foundNothing = matchingMethods == NoMethods;
-               nextMethod : for (int m = matchingMethods.length; --m >= 0;) {
-                       MethodBinding method = matchingMethods[m];
-                       TypeBinding[] toMatch = method.parameters;
-                       if (toMatch.length == argCount) {
-                               for (int p = 0; p < argCount; p++)
-                                       if (toMatch[p] != argumentTypes[p])
-                                               continue nextMethod;
-                               return method;
-                       }
-               }
-       }
-
-       if (foundNothing) {
-               if (isInterface()) {
-                        if (superInterfaces.length == 1)
-                               return superInterfaces[0].getExactMethod(selector, argumentTypes);
-               } else if (superclass != null) {
-                       return superclass.getExactMethod(selector, argumentTypes);
-               }
-       }
-       return null;
-}
-// NOTE: the type of a field of a source type is resolved when needed
-
-public FieldBinding getField(char[] fieldName, boolean needResolve) {
-       // always resolve anyway on source types
-       int fieldLength = fieldName.length;
-       for (int f = fields.length; --f >= 0;) {
-               FieldBinding field = fields[f];
-               if (field.name.length == fieldLength && CharOperation.equals(field.name, fieldName)) {
-                       if (resolveTypeFor(field) != null)
-                               return field;
-
-                       int newSize = fields.length - 1;
-                       if (newSize == 0) {
-                               fields = NoFields;
-                       } else {
-                               FieldBinding[] newFields = new FieldBinding[newSize];
-                               System.arraycopy(fields, 0, newFields, 0, f);
-                               System.arraycopy(fields, f + 1, newFields, f, newSize - f);
-                               fields = newFields;
-                       }
-                       return null;
-               }
-       }
-       return null;
-}
-// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
-
-public MethodBinding[] getMethods(char[] selector) {
-       // handle forward references to potential default abstract methods
-       addDefaultAbstractMethods();
-
-       try{
-               int count = 0;
-               int lastIndex = -1;
-               int selectorLength = selector.length;
-               if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
-                       for (int m = 0, length = methods.length; m < length; m++) {
-                               MethodBinding method = methods[m];
-                               if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) {
-                                       count++;
-                                       lastIndex = m;
-                               }
-                       }
-               } else {
-                       boolean foundProblem = false;
-                       int failed = 0;
-                       for (int m = 0, length = methods.length; m < length; m++) {
-                               MethodBinding method = methods[m];
-                               if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) {
-                                       if (resolveTypesFor(method) == null) {
-                                               foundProblem = true;
-                                               methods[m] = null; // unable to resolve parameters
-                                               failed++;
-                                       } else if (method.returnType == null) {
-                                               foundProblem = true;
-                                       } else {
-                                               count++;
-                                               lastIndex = m;
-                                       }
-                               }
-                       }
-       
-                       if (foundProblem || count > 1) {
-                               for (int m = methods.length; --m >= 0;) {
-                                       MethodBinding method = methods[m];
-                                       if (method != null && method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) {
-                                               AbstractMethodDeclaration methodDecl = null;
-                                               for (int i = 0; i < m; i++) {
-                                                       MethodBinding method2 = methods[i];
-                                                       if (method2 != null && CharOperation.equals(method.selector, method2.selector)) {
-                                                               if (method.areParametersEqual(method2)) {
-                                                                       if (methodDecl == null) {
-                                                                               methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost
-                                                                               scope.problemReporter().duplicateMethodInType(this, methodDecl);
-                                                                               methodDecl.binding = null;
-                                                                               methods[m] = null;
-                                                                               failed++;
-                                                                       }
-                                                                       scope.problemReporter().duplicateMethodInType(this, method2.sourceMethod());
-                                                                       method2.sourceMethod().binding = null;
-                                                                       methods[i] = null;
-                                                                       failed++;
-                                                               }
-                                                       }
-                                               }
-                                               if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
-                                                       method.sourceMethod().binding = null;
-                                                       methods[m] = null;
-                                                       failed++;
-                                               }
-                                       }
-                               }
-       
-                               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)
-                                                       newMethods[n++] = methods[i];
-                                       methods = newMethods;
-                                       return getMethods(selector); // try again now that the problem methods have been removed
-                               }
-                       }
-               }
-               if (count == 1)
-                       return new MethodBinding[] {methods[lastIndex]};
-               if (count > 1) {
-                       MethodBinding[] result = new MethodBinding[count];
-                       count = 0;
-                       for (int m = 0; m <= lastIndex; m++) {
-                               MethodBinding method = methods[m];
-                               if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector))
-                                       result[count++] = method;
-                       }
-                       return result;
-               }
-       } catch(AbortCompilation e){
-               // ensure null methods are removed
-               MethodBinding[] newMethods = null;
-               int count = 0;
-               for (int i = 0, max = methods.length; i < max; i++){
-                       MethodBinding method = methods[i];
-                       if (method == null && newMethods == null){
-                               System.arraycopy(methods, 0, newMethods = new MethodBinding[max], 0, i);
-                       } else if (newMethods != null && method != null) {
-                               newMethods[count++] = method;
-                       }
-               }
-               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>
-*      or null if one does not exist.
-*/
-
-public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) {
-       
-       if (synthetics == null || synthetics[FIELD_EMUL] == null) return null;
-       return (FieldBinding) synthetics[FIELD_EMUL].get(actualOuterLocalVariable);
-}
-public ReferenceBinding[] memberTypes() {
-       return this.memberTypes;
-}
-public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) {
-
-       if (this.synthetics == null) {
-               this.synthetics = new Hashtable[4];
-       }
-       if (this.synthetics[RECEIVER_TYPE_EMUL] == null) {
-               this.synthetics[RECEIVER_TYPE_EMUL] = new Hashtable(5);
-       }
-
-       Hashtable fieldMap = (Hashtable) this.synthetics[RECEIVER_TYPE_EMUL].get(targetField);
-       if (fieldMap == null) {
-               fieldMap = new Hashtable(5);
-               this.synthetics[RECEIVER_TYPE_EMUL].put(targetField, fieldMap);
-       }
-       FieldBinding updatedField = (FieldBinding) fieldMap.get(newDeclaringClass);
-       if (updatedField == null){
-               updatedField = new FieldBinding(targetField, newDeclaringClass);
-               fieldMap.put(newDeclaringClass, updatedField);
-       }
-       return updatedField;
-}
-
-public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod, ReferenceBinding newDeclaringClass) {
-
-       if (this.synthetics == null) {
-               this.synthetics = new Hashtable[4];
-       }
-       if (this.synthetics[RECEIVER_TYPE_EMUL] == null) {
-               this.synthetics[RECEIVER_TYPE_EMUL] = new Hashtable(5);
-       }
-
-
-       Hashtable methodMap = (Hashtable) synthetics[RECEIVER_TYPE_EMUL].get(targetMethod);
-       if (methodMap == null) {
-               methodMap = new Hashtable(5);
-               this.synthetics[RECEIVER_TYPE_EMUL].put(targetMethod, methodMap);
-       }
-       MethodBinding updatedMethod = (MethodBinding) methodMap.get(newDeclaringClass);
-       if (updatedMethod == null){
-               updatedMethod = new MethodBinding(targetMethod, newDeclaringClass);
-               methodMap.put(newDeclaringClass, updatedMethod);
-       }
-       return updatedMethod;
-}
-public boolean hasMemberTypes() {
-    return this.memberTypes.length > 0;
-}
-// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
-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) {
-                               methods[m] = null; // unable to resolve parameters
-                               failed++;
-                       }
-               }
-       
-               for (int m = methods.length; --m >= 0;) {
-                       MethodBinding method = methods[m];
-                       if (method != null) {
-                               AbstractMethodDeclaration methodDecl = null;
-                               for (int i = 0; i < m; i++) {
-                                       MethodBinding method2 = methods[i];
-                                       if (method2 != null && CharOperation.equals(method.selector, method2.selector)) {
-                                               if (method.areParametersEqual(method2)) {
-                                                       if (methodDecl == null) {
-                                                               methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost
-                                                               scope.problemReporter().duplicateMethodInType(this, methodDecl);
-                                                               methodDecl.binding = null;
-                                                               methods[m] = null;
-                                                               failed++;
-                                                       }
-                                                       scope.problemReporter().duplicateMethodInType(this, method2.sourceMethod());
-                                                       method2.sourceMethod().binding = null;
-                                                       methods[i] = null;
-                                                       failed++;
-                                               }
-                                       }
-                               }
-                               if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
-                                       method.sourceMethod().binding = null;
-                                       methods[m] = null;
-                                       failed++;
-                               }
-                       }
-               }
-       
-               if (failed > 0) {
-                       int newSize = methods.length - failed;
-                       if (newSize == 0) {
-                               methods = NoMethods;
-                       } else {
-                               MethodBinding[] newMethods = new MethodBinding[newSize];
-                               for (int m = 0, n = 0, max = methods.length; m < max; m++)
-                                       if (methods[m] != null)
-                                               newMethods[n++] = methods[m];
-                               methods = newMethods;
-                       }
-               }
-       
-               // handle forward references to potential default abstract methods
-               addDefaultAbstractMethods();
-       } catch(AbortCompilation e){
-               // ensure null methods are removed
-               MethodBinding[] newMethods = null;
-               int count = 0;
-               for (int i = 0, max = methods.length; i < max; i++){
-                       MethodBinding method = methods[i];
-                       if (method == null && newMethods == null){
-                               System.arraycopy(methods, 0, newMethods = new MethodBinding[max], 0, i);
-                       } else if (newMethods != null && method != null) {
-                               newMethods[count++] = method;
-                       }
-               }
-               if (newMethods != null){
-                       System.arraycopy(newMethods, 0, methods = new MethodBinding[count], 0, count);
-               }                       
-               modifiers ^= AccUnresolved;
-               throw e;
-       }               
-       modifiers ^= AccUnresolved;
-       return methods;
-}
-private FieldBinding resolveTypeFor(FieldBinding field) {
-       if ((field.modifiers & AccUnresolved) == 0)
-               return field;
-
-       FieldDeclaration[] fieldDecls = scope.referenceContext.fields;
-       for (int f = 0, length = fieldDecls.length; f < length; f++) {
-               if (fieldDecls[f].binding != field)
-                       continue;
-
-               field.type = fieldDecls[f].getTypeBinding(scope);
-               field.modifiers ^= AccUnresolved;
-               if (!field.type.isValidBinding()) {
-                       scope.problemReporter().fieldTypeProblem(this, fieldDecls[f], field.type);
-                       //scope.problemReporter().invalidType(fieldDecls[f].type, field.type);
-                       fieldDecls[f].binding = null;
-                       return null;
-               }
-               if (field.type == VoidBinding) {
-                       scope.problemReporter().variableTypeCannotBeVoid(fieldDecls[f]);
-                       fieldDecls[f].binding = null;
-                       return null;
-               }
-               if (field.type.isArrayType() && ((ArrayBinding) field.type).leafComponentType == VoidBinding) {
-                       scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecls[f]);
-                       fieldDecls[f].binding = null;
-                       return null;
-               }
-               return field;
-       }
-       return null; // should never reach this point
-}
-private MethodBinding resolveTypesFor(MethodBinding method) {
-       if ((method.modifiers & AccUnresolved) == 0)
-               return method;
-
-       AbstractMethodDeclaration methodDecl = method.sourceMethod();
-       TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
-       if (exceptionTypes != null) {
-               int size = exceptionTypes.length;
-               method.thrownExceptions = new ReferenceBinding[size];
-               ReferenceBinding throwable = scope.getJavaLangThrowable();
-               int count = 0;
-               ReferenceBinding resolvedExceptionType;
-               for (int i = 0; i < size; i++) {
-                       resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].getTypeBinding(scope);
-                       if (!resolvedExceptionType.isValidBinding()) {
-                               methodDecl.scope.problemReporter().exceptionTypeProblem(this, methodDecl, exceptionTypes[i], resolvedExceptionType);
-                               //methodDecl.scope.problemReporter().invalidType(exceptionTypes[i], resolvedExceptionType);
-                               continue;
-                       }
-                       if (throwable != resolvedExceptionType && !throwable.isSuperclassOf(resolvedExceptionType)) {
-                               methodDecl.scope.problemReporter().cannotThrowType(this, methodDecl, exceptionTypes[i], resolvedExceptionType);
-                               continue;
-                       }
-                       method.thrownExceptions[count++] = resolvedExceptionType;
-               }
-               if (count < size)
-                       System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count);
-       }
-
-       boolean foundArgProblem = false;
-       Argument[] arguments = methodDecl.arguments;
-       if (arguments != null) {
-               int size = arguments.length;
-               method.parameters = new TypeBinding[size];
-               for (int i = 0; i < size; i++) {
-                       Argument arg = arguments[i];
-                       method.parameters[i] = arg.type.getTypeBinding(scope);
-                       if (!method.parameters[i].isValidBinding()) {
-                               methodDecl.scope.problemReporter().argumentTypeProblem(this, methodDecl, arg, method.parameters[i]);
-                               //methodDecl.scope.problemReporter().invalidType(arg, method.parameters[i]);
-                               foundArgProblem = true;
-                       } else if (method.parameters[i] == VoidBinding) {
-                               methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg);
-                               foundArgProblem = true;
-                       } else if (method.parameters[i].isArrayType() && ((ArrayBinding) method.parameters[i]).leafComponentType == VoidBinding) {
-                               methodDecl.scope.problemReporter().argumentTypeCannotBeVoidArray(this, methodDecl, arg);
-                               foundArgProblem = true;
-                       }
-               }
-       }
-
-       boolean foundReturnTypeProblem = false;
-       if (!method.isConstructor()) {
-               TypeReference returnType = ((MethodDeclaration) methodDecl).returnType;
-               if (returnType == null) {
-                       methodDecl.scope.problemReporter().missingReturnType(methodDecl);
-                       method.returnType = null;
-                       foundReturnTypeProblem = true;
-               } else {
-                       method.returnType = returnType.getTypeBinding(scope);
-                       if (!method.returnType.isValidBinding()) {
-                               methodDecl.scope.problemReporter().returnTypeProblem(this, (MethodDeclaration) methodDecl, method.returnType);
-                               //methodDecl.scope.problemReporter().invalidType(returnType, method.returnType);
-                               method.returnType = null;
-                               foundReturnTypeProblem = true;
-                       } else if (method.returnType.isArrayType() && ((ArrayBinding) method.returnType).leafComponentType == VoidBinding) {
-                               methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray(this, (MethodDeclaration) methodDecl);
-                               method.returnType = null;
-                               foundReturnTypeProblem = true;
-                       }
-               }
-       }
-       if (foundArgProblem) {
-               methodDecl.binding = null;
-               return null;
-       }
-       if (foundReturnTypeProblem)
-               return method; // but its still unresolved with a null return type & is still connected to its method declaration
-
-       method.modifiers ^= AccUnresolved;
-       return method;
-}
-public final int sourceEnd() {
-       return scope.referenceContext.sourceEnd;
-}
-public final int sourceStart() {
-       return scope.referenceContext.sourceStart;
-}
-public ReferenceBinding superclass() {
-       return superclass;
-}
-public ReferenceBinding[] superInterfaces() {
-       return superInterfaces;
-}
-public SyntheticAccessMethodBinding[] syntheticAccessMethods() {
-       
-       if (synthetics == null || synthetics[METHOD_EMUL] == null || synthetics[METHOD_EMUL].size() == 0) return null;
-
-       // difficult to compute size up front because of the embedded arrays so assume there is only 1
-       int index = 0;
-       SyntheticAccessMethodBinding[] bindings = new SyntheticAccessMethodBinding[1];
-       Enumeration fieldsOrMethods = synthetics[METHOD_EMUL].keys();
-       while (fieldsOrMethods.hasMoreElements()) {
-
-               Object fieldOrMethod = fieldsOrMethods.nextElement();
-
-               if (fieldOrMethod instanceof MethodBinding) {
-
-                       SyntheticAccessMethodBinding[] methodAccessors = (SyntheticAccessMethodBinding[]) synthetics[METHOD_EMUL].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_EMUL].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]; // read access
-                       if (fieldAccessors[1] != null) 
-                               bindings[index++] = fieldAccessors[1]; // write access
-               }
-       }
-
-       // sort them in according to their own indexes
-       int length;
-       SyntheticAccessMethodBinding[] sortedBindings = new SyntheticAccessMethodBinding[length = bindings.length];
-       for (int i = 0; i < length; i++){
-               SyntheticAccessMethodBinding binding = bindings[i];
-               sortedBindings[binding.index] = binding;
-       }
-       return sortedBindings;
-}
-/**
- * Answer the collection of synthetic fields to append into the classfile
- */
-public FieldBinding[] syntheticFields() {
-       
-       if (synthetics == null) return null;
-
-       int fieldSize = synthetics[FIELD_EMUL] == null ? 0 : synthetics[FIELD_EMUL].size();
-       int literalSize = synthetics[CLASS_LITERAL_EMUL] == null ? 0 :synthetics[CLASS_LITERAL_EMUL].size();
-       int totalSize = fieldSize + literalSize;
-       if (totalSize == 0) return null;
-       FieldBinding[] bindings = new FieldBinding[totalSize];
-
-       // add innerclass synthetics
-       if (synthetics[FIELD_EMUL] != null){
-               Enumeration elements = synthetics[FIELD_EMUL].elements();
-               for (int i = 0; i < fieldSize; i++) {
-                       SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.nextElement();
-                       bindings[synthBinding.index] = synthBinding;
-               }
-       }
-       // add class literal synthetics
-       if (synthetics[CLASS_LITERAL_EMUL] != null){
-               Enumeration elements = synthetics[CLASS_LITERAL_EMUL].elements();
-               for (int i = 0; i < literalSize; i++) {
-                       SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.nextElement();
-                       bindings[fieldSize+synthBinding.index] = synthBinding;
-               }
-       }
-       return bindings;
-}
-public String toString() {
-       String s = "(id="+(id == NoId ? "NoId" : (""+id) ) +")\n"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-4$ //$NON-NLS-1$
-
-       if (isDeprecated()) s += "deprecated "; //$NON-NLS-1$
-       if (isPublic()) s += "public "; //$NON-NLS-1$
-       if (isProtected()) s += "protected "; //$NON-NLS-1$
-       if (isPrivate()) s += "private "; //$NON-NLS-1$
-       if (isAbstract() && isClass()) s += "abstract "; //$NON-NLS-1$
-       if (isStatic() && isNestedType()) s += "static "; //$NON-NLS-1$
-       if (isFinal()) s += "final "; //$NON-NLS-1$
-
-       s += isInterface() ? "interface " : "class "; //$NON-NLS-1$ //$NON-NLS-2$
-       s += (compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"; //$NON-NLS-1$
-
-       s += "\n\textends "; //$NON-NLS-1$
-       s += (superclass != null) ? superclass.debugName() : "NULL TYPE"; //$NON-NLS-1$
-
-       if (superInterfaces != null) {
-               if (superInterfaces != NoSuperInterfaces) {
-                       s += "\n\timplements : "; //$NON-NLS-1$
-                       for (int i = 0, length = superInterfaces.length; i < length; i++) {
-                               if (i  > 0)
-                                       s += ", "; //$NON-NLS-1$
-                               s += (superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"; //$NON-NLS-1$
-                       }
-               }
-       } else {
-               s += "NULL SUPERINTERFACES"; //$NON-NLS-1$
-       }
-
-       if (enclosingType() != null) {
-               s += "\n\tenclosing type : "; //$NON-NLS-1$
-               s += enclosingType().debugName();
-       }
-
-       if (fields != null) {
-               if (fields != NoFields) {
-                       s += "\n/*   fields   */"; //$NON-NLS-1$
-                       for (int i = 0, length = fields.length; i < length; i++)
-                               s += (fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"; //$NON-NLS-1$ //$NON-NLS-2$
-               }
-       } else {
-               s += "NULL FIELDS"; //$NON-NLS-1$
-       }
-
-       if (methods != null) {
-               if (methods != NoMethods) {
-                       s += "\n/*   methods   */"; //$NON-NLS-1$
-                       for (int i = 0, length = methods.length; i < length; i++)
-                               s += (methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"; //$NON-NLS-1$ //$NON-NLS-2$
-               }
-       } else {
-               s += "NULL METHODS"; //$NON-NLS-1$
-       }
-
-       if (memberTypes != null) {
-               if (memberTypes != NoMemberTypes) {
-                       s += "\n/*   members   */"; //$NON-NLS-1$
-                       for (int i = 0, length = memberTypes.length; i < length; i++)
-                               s += (memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"; //$NON-NLS-1$ //$NON-NLS-2$
-               }
-       } else {
-               s += "NULL MEMBER TYPES"; //$NON-NLS-1$
-       }
-
-       s += "\n\n\n"; //$NON-NLS-1$
-       return s;
-}
-void verifyMethods(MethodVerifier verifier) {
-       verifier.verify(this);
-
-       for (int i = memberTypes.length; --i >= 0;)
-                ((SourceTypeBinding) memberTypes[i]).verifyMethods(verifier);
-}
-
-/* Answer the synthetic field for <targetEnclosingType>
-*      or null if one does not exist.
-*/
-
-public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
-
-       if (synthetics == null || synthetics[FIELD_EMUL] == null) return null;
-       FieldBinding field = (FieldBinding) synthetics[FIELD_EMUL].get(targetEnclosingType);
-       if (field != null) return field;
-
-       // type compatibility : to handle cases such as
-       // 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 accessFields = synthetics[FIELD_EMUL].elements();
-               while (accessFields.hasMoreElements()) {
-                       field = (FieldBinding) accessFields.nextElement();
-                       if (CharOperation.prefixEquals(SyntheticArgumentBinding.EnclosingInstancePrefix, field.name)
-                               && targetEnclosingType.isSuperclassOf((ReferenceBinding) field.type))
-                                       return field;
-               }
-       }
-       return null;
-}
-}