A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / MethodVerifier.java
index cf46cd2..98c7fd2 100644 (file)
@@ -18,442 +18,684 @@ import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject;
 
 public final class MethodVerifier implements TagBits, TypeConstants {
        SourceTypeBinding type;
+
        HashtableOfObject inheritedMethods;
+
        HashtableOfObject currentMethods;
+
        ReferenceBinding runtimeException;
+
        ReferenceBinding errorException;
+
        LookupEnvironment environment;
-/*
-Binding creation is responsible for reporting all problems with types:
-       - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - abstract/final)
-               - plus invalid modifiers given the context (the verifier did not do this before)
-       - qualified name collisions between a type and a package (types in default packages are excluded)
-       - all type hierarchy problems:
-               - cycles in the superclass or superinterface hierarchy
-               - an ambiguous, invisible or missing superclass or superinterface
-               - extending a final class
-               - extending an interface instead of a class
-               - implementing a class instead of an interface
-               - implementing the same interface more than once (ie. duplicate interfaces)
-       - with nested types:
-               - shadowing an enclosing type's source name
-               - defining a static class or interface inside a non-static nested class
-               - defining an interface as a local type (local types can only be classes)
-*/
-public MethodVerifier(LookupEnvironment environment) {
-       this.type = null;  // Initialized with the public method verify(SourceTypeBinding)
-       this.inheritedMethods = null;
-       this.currentMethods = null;
-       this.runtimeException = null;
-       this.errorException = null;
-       this.environment = environment;
-}
-private void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length) {
-       currentMethod.modifiers |= CompilerModifiers.AccOverriding;
-       for (int i = length; --i >= 0;) {
-               MethodBinding inheritedMethod = methods[i];
-               if (!currentMethod.isAbstract() && inheritedMethod.isAbstract())
-                       currentMethod.modifiers |= CompilerModifiers.AccImplementing;
-
-               if (currentMethod.returnType != inheritedMethod.returnType) {
-                       this.problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod);
-               } else if (currentMethod.isStatic() != inheritedMethod.isStatic()) {  // Cannot override a static method or hide an instance method
-                       this.problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod);
-               } else {
-                       if (currentMethod.thrownExceptions != NoExceptions)
-                               this.checkExceptions(currentMethod, inheritedMethod);
-                       if (inheritedMethod.isFinal())
-                               this.problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
-                       if (!this.isAsVisible(currentMethod, inheritedMethod))
-                               this.problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod);
-//                     if (inheritedMethod.isViewedAsDeprecated())
-//                             if (!currentMethod.isViewedAsDeprecated() || environment.options.reportDeprecationInsideDeprecatedCode)
-//                                     this.problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod);
-               }
+
+       /*
+        * Binding creation is responsible for reporting all problems with types: -
+        * all modifier problems (duplicates & multiple visibility modifiers +
+        * incompatible combinations - abstract/final) - plus invalid modifiers
+        * given the context (the verifier did not do this before) - qualified name
+        * collisions between a type and a package (types in default packages are
+        * excluded) - all type hierarchy problems: - cycles in the superclass or
+        * superinterface hierarchy - an ambiguous, invisible or missing superclass
+        * or superinterface - extending a final class - extending an interface
+        * instead of a class - implementing a class instead of an interface -
+        * implementing the same interface more than once (ie. duplicate interfaces) -
+        * with nested types: - shadowing an enclosing type's source name - defining
+        * a static class or interface inside a non-static nested class - defining
+        * an interface as a local type (local types can only be classes)
+        */
+       public MethodVerifier(LookupEnvironment environment) {
+               this.type = null; // Initialized with the public method
+                                                       // verify(SourceTypeBinding)
+               this.inheritedMethods = null;
+               this.currentMethods = null;
+               this.runtimeException = null;
+               this.errorException = null;
+               this.environment = environment;
        }
-}
-/*
-"8.4.4"
-Verify that newExceptions are all included in inheritedExceptions.
-Assumes all exceptions are valid and throwable.
-Unchecked exceptions (compatible with runtime & error) are ignored (see the spec on pg. 203).
-*/
-private void checkExceptions(MethodBinding newMethod, MethodBinding inheritedMethod) {
-       ReferenceBinding[] newExceptions = newMethod.thrownExceptions;
-       ReferenceBinding[] inheritedExceptions = inheritedMethod.thrownExceptions;
-       for (int i = newExceptions.length; --i >= 0;) {
-               ReferenceBinding newException = newExceptions[i];
-               int j = inheritedExceptions.length;
-               while (--j > -1 && !this.isSameClassOrSubclassOf(newException, inheritedExceptions[j]));
-               if (j == -1)
-                       if (!(newException.isCompatibleWith(this.runtimeException()) || newException.isCompatibleWith(this.errorException())))
-                               this.problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException);
+
+       private void checkAgainstInheritedMethods(MethodBinding currentMethod,
+                       MethodBinding[] methods, int length) {
+               currentMethod.modifiers |= CompilerModifiers.AccOverriding;
+               for (int i = length; --i >= 0;) {
+                       MethodBinding inheritedMethod = methods[i];
+                       if (!currentMethod.isAbstract() && inheritedMethod.isAbstract())
+                               currentMethod.modifiers |= CompilerModifiers.AccImplementing;
+
+                       if (currentMethod.returnType != inheritedMethod.returnType) {
+                               this.problemReporter(currentMethod).incompatibleReturnType(
+                                               currentMethod, inheritedMethod);
+                       } else if (currentMethod.isStatic() != inheritedMethod.isStatic()) { // Cannot
+                                                                                                                                                                       // override
+                                                                                                                                                                       // a
+                                                                                                                                                                       // static
+                                                                                                                                                                       // method
+                                                                                                                                                                       // or
+                                                                                                                                                                       // hide
+                                                                                                                                                                       // an
+                                                                                                                                                                       // instance
+                                                                                                                                                                       // method
+                               this.problemReporter(currentMethod).staticAndInstanceConflict(
+                                               currentMethod, inheritedMethod);
+                       } else {
+                               if (currentMethod.thrownExceptions != NoExceptions)
+                                       this.checkExceptions(currentMethod, inheritedMethod);
+                               if (inheritedMethod.isFinal())
+                                       this.problemReporter(currentMethod)
+                                                       .finalMethodCannotBeOverridden(currentMethod,
+                                                                       inheritedMethod);
+                               if (!this.isAsVisible(currentMethod, inheritedMethod))
+                                       this.problemReporter(currentMethod).visibilityConflict(
+                                                       currentMethod, inheritedMethod);
+                               // if (inheritedMethod.isViewedAsDeprecated())
+                               // if (!currentMethod.isViewedAsDeprecated() ||
+                               // environment.options.reportDeprecationInsideDeprecatedCode)
+                               // this.problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod,
+                               // inheritedMethod);
+                       }
+               }
        }
-}
-private void checkInheritedMethods(MethodBinding[] methods, int length) {
-       TypeBinding returnType = methods[0].returnType;
-       int index = length;
-       while (--index > 0 && returnType == methods[index].returnType);
-       if (index > 0) {  // All inherited methods do NOT have the same vmSignature
-               this.problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length);
-               return;
+
+       /*
+        * "8.4.4" Verify that newExceptions are all included in
+        * inheritedExceptions. Assumes all exceptions are valid and throwable.
+        * Unchecked exceptions (compatible with runtime & error) are ignored (see
+        * the spec on pg. 203).
+        */
+       private void checkExceptions(MethodBinding newMethod,
+                       MethodBinding inheritedMethod) {
+               ReferenceBinding[] newExceptions = newMethod.thrownExceptions;
+               ReferenceBinding[] inheritedExceptions = inheritedMethod.thrownExceptions;
+               for (int i = newExceptions.length; --i >= 0;) {
+                       ReferenceBinding newException = newExceptions[i];
+                       int j = inheritedExceptions.length;
+                       while (--j > -1
+                                       && !this.isSameClassOrSubclassOf(newException,
+                                                       inheritedExceptions[j]))
+                               ;
+                       if (j == -1)
+                               if (!(newException.isCompatibleWith(this.runtimeException()) || newException
+                                               .isCompatibleWith(this.errorException())))
+                                       this.problemReporter(newMethod)
+                                                       .incompatibleExceptionInThrowsClause(this.type,
+                                                                       newMethod, inheritedMethod, newException);
+               }
        }
 
-       MethodBinding concreteMethod = null;
-       if (!type.isInterface()) {  // ignore concrete methods for interfaces
-               for (int i = length; --i >= 0;) {  // Remember that only one of the methods can be non-abstract
-                       if (!methods[i].isAbstract()) {
-                               concreteMethod = methods[i];
-                               break;
+       private void checkInheritedMethods(MethodBinding[] methods, int length) {
+               TypeBinding returnType = methods[0].returnType;
+               int index = length;
+               while (--index > 0 && returnType == methods[index].returnType)
+                       ;
+               if (index > 0) { // All inherited methods do NOT have the same
+                                                       // vmSignature
+                       this.problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(
+                                       this.type, methods, length);
+                       return;
+               }
+
+               MethodBinding concreteMethod = null;
+               if (!type.isInterface()) { // ignore concrete methods for interfaces
+                       for (int i = length; --i >= 0;) { // Remember that only one of the
+                                                                                               // methods can be non-abstract
+                               if (!methods[i].isAbstract()) {
+                                       concreteMethod = methods[i];
+                                       break;
+                               }
                        }
                }
-       }
-       if (concreteMethod == null) {
-               if (this.type.isClass() && !this.type.isAbstract()) {
-                       for (int i = length; --i >= 0;)
-                               if (!mustImplementAbstractMethod(methods[i])) return;  // have already reported problem against the concrete superclass
-
-                       TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
-                       if (typeDeclaration != null) {
-                               MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(methods[0]);
-                               missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]);
-                       } else {
-                               this.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]);
+               if (concreteMethod == null) {
+                       if (this.type.isClass() && !this.type.isAbstract()) {
+                               for (int i = length; --i >= 0;)
+                                       if (!mustImplementAbstractMethod(methods[i]))
+                                               return; // have already reported problem against the
+                                                               // concrete superclass
+
+                               TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
+                               if (typeDeclaration != null) {
+                                       MethodDeclaration missingAbstractMethod = typeDeclaration
+                                                       .addMissingAbstractMethodFor(methods[0]);
+                                       missingAbstractMethod.scope.problemReporter()
+                                                       .abstractMethodMustBeImplemented(this.type,
+                                                                       methods[0]);
+                               } else {
+                                       this.problemReporter().abstractMethodMustBeImplemented(
+                                                       this.type, methods[0]);
+                               }
                        }
+                       return;
                }
-               return;
+
+               MethodBinding[] abstractMethods = new MethodBinding[length - 1];
+               index = 0;
+               for (int i = length; --i >= 0;)
+                       if (methods[i] != concreteMethod)
+                               abstractMethods[index++] = methods[i];
+
+               // Remember that interfaces can only define public instance methods
+               if (concreteMethod.isStatic())
+                       // Cannot inherit a static method which is specified as an instance
+                       // method by an interface
+                       this.problemReporter().staticInheritedMethodConflicts(type,
+                                       concreteMethod, abstractMethods);
+               if (!concreteMethod.isPublic())
+                       // Cannot reduce visibility of a public method specified by an
+                       // interface
+                       this.problemReporter().inheritedMethodReducesVisibility(type,
+                                       concreteMethod, abstractMethods);
+               if (concreteMethod.thrownExceptions != NoExceptions)
+                       for (int i = abstractMethods.length; --i >= 0;)
+                               this.checkExceptions(concreteMethod, abstractMethods[i]);
        }
 
-       MethodBinding[] abstractMethods = new MethodBinding[length - 1];
-       index = 0;
-       for (int i = length; --i >= 0;)
-               if (methods[i] != concreteMethod)
-                       abstractMethods[index++] = methods[i];
-
-       // Remember that interfaces can only define public instance methods
-       if (concreteMethod.isStatic())
-               // Cannot inherit a static method which is specified as an instance method by an interface
-               this.problemReporter().staticInheritedMethodConflicts(type, concreteMethod, abstractMethods);   
-       if (!concreteMethod.isPublic())
-               // Cannot reduce visibility of a public method specified by an interface
-               this.problemReporter().inheritedMethodReducesVisibility(type, concreteMethod, abstractMethods);
-       if (concreteMethod.thrownExceptions != NoExceptions)
-               for (int i = abstractMethods.length; --i >= 0;)
-                       this.checkExceptions(concreteMethod, abstractMethods[i]);
-}
-/*
-For each inherited method identifier (message pattern - vm signature minus the return type)
-       if current method exists
-               if current's vm signature does not match an inherited signature then complain 
-               else compare current's exceptions & visibility against each inherited method
-       else
-               if inherited methods = 1
-                       if inherited is abstract && type is NOT an interface or abstract, complain
-               else
-                       if vm signatures do not match complain
-                       else
-                               find the concrete implementation amongst the abstract methods (can only be 1)
-                               if one exists then
-                                       it must be a public instance method
-                                       compare concrete's exceptions against each abstract method
-                               else
-                                       complain about missing implementation only if type is NOT an interface or abstract
-*/
-private void checkMethods() { 
-       boolean mustImplementAbstractMethods = this.type.isClass() && !this.type.isAbstract();
-       char[][] methodSelectors = this.inheritedMethods.keyTable;
-       for (int s = methodSelectors.length; --s >= 0;) {
-               if (methodSelectors[s] != null) {
-                       MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(methodSelectors[s]);
-                       MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s];
-
-                       int index = -1;
-                       MethodBinding[] matchingInherited = new MethodBinding[inherited.length];
-                       if (current != null) {
-                               for (int i = 0, length1 = current.length; i < length1; i++) {
-                                       while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods
-                                       MethodBinding currentMethod = current[i];
-                                       for (int j = 0, length2 = inherited.length; j < length2; j++) {
-                                               if (inherited[j] != null && currentMethod.areParametersEqual(inherited[j])) {
-                                                       matchingInherited[++index] = inherited[j];
-                                                       inherited[j] = null; // do not want to find it again
+       /*
+        * For each inherited method identifier (message pattern - vm signature
+        * minus the return type) if current method exists if current's vm signature
+        * does not match an inherited signature then complain else compare
+        * current's exceptions & visibility against each inherited method else if
+        * inherited methods = 1 if inherited is abstract && type is NOT an
+        * interface or abstract, complain else if vm signatures do not match
+        * complain else find the concrete implementation amongst the abstract
+        * methods (can only be 1) if one exists then it must be a public instance
+        * method compare concrete's exceptions against each abstract method else
+        * complain about missing implementation only if type is NOT an interface or
+        * abstract
+        */
+       private void checkMethods() {
+               boolean mustImplementAbstractMethods = this.type.isClass()
+                               && !this.type.isAbstract();
+               char[][] methodSelectors = this.inheritedMethods.keyTable;
+               for (int s = methodSelectors.length; --s >= 0;) {
+                       if (methodSelectors[s] != null) {
+                               MethodBinding[] current = (MethodBinding[]) this.currentMethods
+                                               .get(methodSelectors[s]);
+                               MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s];
+
+                               int index = -1;
+                               MethodBinding[] matchingInherited = new MethodBinding[inherited.length];
+                               if (current != null) {
+                                       for (int i = 0, length1 = current.length; i < length1; i++) {
+                                               while (index >= 0)
+                                                       matchingInherited[index--] = null; // clear the
+                                                                                                                               // previous
+                                                                                                                               // contents of
+                                                                                                                               // the matching
+                                                                                                                               // methods
+                                               MethodBinding currentMethod = current[i];
+                                               for (int j = 0, length2 = inherited.length; j < length2; j++) {
+                                                       if (inherited[j] != null
+                                                                       && currentMethod
+                                                                                       .areParametersEqual(inherited[j])) {
+                                                               matchingInherited[++index] = inherited[j];
+                                                               inherited[j] = null; // do not want to find
+                                                                                                               // it again
+                                                       }
                                                }
+                                               if (index >= 0)
+                                                       this.checkAgainstInheritedMethods(currentMethod,
+                                                                       matchingInherited, index + 1); // pass in
+                                                                                                                                       // the
+                                                                                                                                       // length of
+                                                                                                                                       // matching
                                        }
-                                       if (index >= 0)
-                                               this.checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1); // pass in the length of matching
                                }
-                       }
-                       for (int i = 0, length = inherited.length; i < length; i++) {
-                               while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods
-                               if (inherited[i] != null) {
-                                       matchingInherited[++index] = inherited[i];
-                                       for (int j = i + 1; j < length; j++) {
-                                               if (inherited[j] != null && inherited[i].areParametersEqual(inherited[j])) {
-                                                       matchingInherited[++index] = inherited[j];
-                                                       inherited[j] = null; // do not want to find it again
+                               for (int i = 0, length = inherited.length; i < length; i++) {
+                                       while (index >= 0)
+                                               matchingInherited[index--] = null; // clear the
+                                                                                                                       // previous contents
+                                                                                                                       // of the matching
+                                                                                                                       // methods
+                                       if (inherited[i] != null) {
+                                               matchingInherited[++index] = inherited[i];
+                                               for (int j = i + 1; j < length; j++) {
+                                                       if (inherited[j] != null
+                                                                       && inherited[i]
+                                                                                       .areParametersEqual(inherited[j])) {
+                                                               matchingInherited[++index] = inherited[j];
+                                                               inherited[j] = null; // do not want to find
+                                                                                                               // it again
+                                                       }
                                                }
                                        }
-                               }
-                               if (index > 0) {
-                                       this.checkInheritedMethods(matchingInherited, index + 1); // pass in the length of matching
-                               } else if (mustImplementAbstractMethods && index == 0 && matchingInherited[0].isAbstract()) {
-                                       if (mustImplementAbstractMethod(matchingInherited[0])) {
-                                               TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
-                                               if (typeDeclaration != null) {
-                                                       MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(matchingInherited[0]);
-                                                       missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]);
-                                               } else {
-                                                       this.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]);
+                                       if (index > 0) {
+                                               this
+                                                               .checkInheritedMethods(matchingInherited,
+                                                                               index + 1); // pass in the length of
+                                                                                                       // matching
+                                       } else if (mustImplementAbstractMethods && index == 0
+                                                       && matchingInherited[0].isAbstract()) {
+                                               if (mustImplementAbstractMethod(matchingInherited[0])) {
+                                                       TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
+                                                       if (typeDeclaration != null) {
+                                                               MethodDeclaration missingAbstractMethod = typeDeclaration
+                                                                               .addMissingAbstractMethodFor(matchingInherited[0]);
+                                                               missingAbstractMethod.scope
+                                                                               .problemReporter()
+                                                                               .abstractMethodMustBeImplemented(
+                                                                                               this.type, matchingInherited[0]);
+                                                       } else {
+                                                               this
+                                                                               .problemReporter()
+                                                                               .abstractMethodMustBeImplemented(
+                                                                                               this.type, matchingInherited[0]);
+                                                       }
                                                }
                                        }
                                }
                        }
                }
        }
-}
-private void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) {
-       ReferenceBinding superType = this.type.superclass();
-       char[] selector = abstractMethod.selector;
-       do {
-               if (!superType.isValidBinding()) return;
-               if (!superType.isAbstract()) return; // closer non abstract super type will be flagged instead
-
-               MethodBinding[] methods = superType.getMethods(selector);
-               nextMethod : for (int m = methods.length; --m >= 0;) {
-                       MethodBinding method = methods[m];
-                       if (method.returnType != abstractMethod.returnType || !method.areParametersEqual(abstractMethod))
-                               continue nextMethod;
-                       if (method.isPrivate() || method.isConstructor() || method.isDefaultAbstract())
-                               continue nextMethod;
-                       if (superType.fPackage == abstractMethod.declaringClass.fPackage) return; // found concrete implementation of abstract method in same package
-               }
-       } while ((superType = superType.superclass()) != abstractMethod.declaringClass);
 
-       // non visible abstract methods cannot be overridden so the type must be defined abstract
-       this.problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod);
-}
-/*
-Binding creation is responsible for reporting:
-       - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations)
-               - plus invalid modifiers given the context... examples:
-                       - interface methods can only be public
-                       - abstract methods can only be defined by abstract classes
-       - collisions... 2 methods with identical vmSelectors
-       - multiple methods with the same message pattern but different return types
-       - ambiguous, invisible or missing return/argument/exception types
-       - check the type of any array is not void
-       - check that each exception type is Throwable or a subclass of it
-*/
-private void computeInheritedMethods() {
-       this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type
-       ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
-       int lastPosition = 0;
-       interfacesToVisit[lastPosition] = type.superInterfaces();
-
-       ReferenceBinding superType = this.type.isClass()
-               ? this.type.superclass()
-               : this.type.scope.getJavaLangObject(); // check interface methods against Object
-       MethodBinding[] nonVisibleDefaultMethods = null;
-       int nonVisibleCount = 0;
-
-       while (superType != null) {
-               if (superType.isValidBinding()) {
-                       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;
-                       }
+       private void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) {
+               ReferenceBinding superType = this.type.superclass();
+               char[] selector = abstractMethod.selector;
+               do {
+                       if (!superType.isValidBinding())
+                               return;
+                       if (!superType.isAbstract())
+                               return; // closer non abstract super type will be flagged
+                                               // instead
 
-                       MethodBinding[] methods = superType.methods();
-                       nextMethod : for (int m = methods.length; --m >= 0;) {
+                       MethodBinding[] methods = superType.getMethods(selector);
+                       nextMethod: for (int m = methods.length; --m >= 0;) {
                                MethodBinding method = methods[m];
-                               if (!(method.isPrivate() || method.isConstructor() || method.isDefaultAbstract())) { // look at all methods which are NOT private or constructors or default abstract
-                                       MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(method.selector);
-                                       if (existingMethods != null) {
-                                               for (int i = 0, length = existingMethods.length; i < length; i++) {
-                                                       if (method.returnType == existingMethods[i].returnType && method.areParametersEqual(existingMethods[i])) {
-                                                               if (method.isDefault() && method.isAbstract() && method.declaringClass.fPackage != type.fPackage)
-                                                                       checkPackagePrivateAbstractMethod(method);
-                                                               continue nextMethod;
+                               if (method.returnType != abstractMethod.returnType
+                                               || !method.areParametersEqual(abstractMethod))
+                                       continue nextMethod;
+                               if (method.isPrivate() || method.isConstructor()
+                                               || method.isDefaultAbstract())
+                                       continue nextMethod;
+                               if (superType.fPackage == abstractMethod.declaringClass.fPackage)
+                                       return; // found concrete implementation of abstract method
+                                                       // in same package
+                       }
+               } while ((superType = superType.superclass()) != abstractMethod.declaringClass);
+
+               // non visible abstract methods cannot be overridden so the type must be
+               // defined abstract
+               this.problemReporter().abstractMethodCannotBeOverridden(this.type,
+                               abstractMethod);
+       }
+
+       /*
+        * Binding creation is responsible for reporting: - all modifier problems
+        * (duplicates & multiple visibility modifiers + incompatible combinations) -
+        * plus invalid modifiers given the context... examples: - interface methods
+        * can only be public - abstract methods can only be defined by abstract
+        * classes - collisions... 2 methods with identical vmSelectors - multiple
+        * methods with the same message pattern but different return types -
+        * ambiguous, invisible or missing return/argument/exception types - check
+        * the type of any array is not void - check that each exception type is
+        * Throwable or a subclass of it
+        */
+       private void computeInheritedMethods() {
+               this.inheritedMethods = new HashtableOfObject(51); // maps method
+                                                                                                                       // selectors to an
+                                                                                                                       // array of
+                                                                                                                       // methods... must
+                                                                                                                       // search to match
+                                                                                                                       // paramaters &
+                                                                                                                       // return type
+               ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
+               int lastPosition = 0;
+               interfacesToVisit[lastPosition] = type.superInterfaces();
+
+               ReferenceBinding superType = this.type.isClass() ? this.type
+                               .superclass() : this.type.scope.getJavaLangObject(); // check
+                                                                                                                                               // interface
+                                                                                                                                               // methods
+                                                                                                                                               // against
+                                                                                                                                               // Object
+               MethodBinding[] nonVisibleDefaultMethods = null;
+               int nonVisibleCount = 0;
+
+               while (superType != null) {
+                       if (superType.isValidBinding()) {
+                               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;
+                               }
+
+                               MethodBinding[] methods = superType.methods();
+                               nextMethod: for (int m = methods.length; --m >= 0;) {
+                                       MethodBinding method = methods[m];
+                                       if (!(method.isPrivate() || method.isConstructor() || method
+                                                       .isDefaultAbstract())) { // look at all methods
+                                                                                                               // which are NOT private
+                                                                                                               // or constructors or
+                                                                                                               // default abstract
+                                               MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods
+                                                               .get(method.selector);
+                                               if (existingMethods != null) {
+                                                       for (int i = 0, length = existingMethods.length; i < length; i++) {
+                                                               if (method.returnType == existingMethods[i].returnType
+                                                                               && method
+                                                                                               .areParametersEqual(existingMethods[i])) {
+                                                                       if (method.isDefault()
+                                                                                       && method.isAbstract()
+                                                                                       && method.declaringClass.fPackage != type.fPackage)
+                                                                               checkPackagePrivateAbstractMethod(method);
+                                                                       continue nextMethod;
+                                                               }
                                                        }
                                                }
-                                       }
-                                       if (nonVisibleDefaultMethods != null)
-                                               for (int i = 0; i < nonVisibleCount; i++)
-                                                       if (method.returnType == nonVisibleDefaultMethods[i].returnType
-                                                               && CharOperation.equals(method.selector, nonVisibleDefaultMethods[i].selector)
-                                                               && method.areParametersEqual(nonVisibleDefaultMethods[i])) 
+                                               if (nonVisibleDefaultMethods != null)
+                                                       for (int i = 0; i < nonVisibleCount; i++)
+                                                               if (method.returnType == nonVisibleDefaultMethods[i].returnType
+                                                                               && CharOperation
+                                                                                               .equals(
+                                                                                                               method.selector,
+                                                                                                               nonVisibleDefaultMethods[i].selector)
+                                                                               && method
+                                                                                               .areParametersEqual(nonVisibleDefaultMethods[i]))
                                                                        continue nextMethod;
 
-                                       if (!(method.isDefault() && method.declaringClass.fPackage != type.fPackage)) { // ignore methods which have default visibility and are NOT defined in another package
-                                               if (existingMethods == null)
-                                                       existingMethods = new MethodBinding[1];
-                                               else
-                                                       System.arraycopy(existingMethods, 0,
-                                                               (existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1);
-                                               existingMethods[existingMethods.length - 1] = method;
-                                               this.inheritedMethods.put(method.selector, existingMethods);
-                                       } else {
-                                               if (nonVisibleDefaultMethods == null)
-                                                       nonVisibleDefaultMethods = new MethodBinding[10];
-                                               else if (nonVisibleCount == nonVisibleDefaultMethods.length)
-                                                       System.arraycopy(nonVisibleDefaultMethods, 0,
-                                                               (nonVisibleDefaultMethods = new MethodBinding[nonVisibleCount * 2]), 0, nonVisibleCount);
-                                               nonVisibleDefaultMethods[nonVisibleCount++] = method;
-
-                                               if (method.isAbstract() && !this.type.isAbstract()) // non visible abstract methods cannot be overridden so the type must be defined abstract
-                                                       this.problemReporter().abstractMethodCannotBeOverridden(this.type, method);
-
-                                               MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(method.selector);
-                                               if (current != null) { // non visible methods cannot be overridden so a warning is issued
-                                                       foundMatch : for (int i = 0, length = current.length; i < length; i++) {
-                                                               if (method.returnType == current[i].returnType && method.areParametersEqual(current[i])) {
-                                                                       this.problemReporter().overridesPackageDefaultMethod(current[i], method);
-                                                                       break foundMatch;
+                                               if (!(method.isDefault() && method.declaringClass.fPackage != type.fPackage)) { // ignore
+                                                                                                                                                                                                               // methods
+                                                                                                                                                                                                               // which
+                                                                                                                                                                                                               // have
+                                                                                                                                                                                                               // default
+                                                                                                                                                                                                               // visibility
+                                                                                                                                                                                                               // and
+                                                                                                                                                                                                               // are
+                                                                                                                                                                                                               // NOT
+                                                                                                                                                                                                               // defined
+                                                                                                                                                                                                               // in
+                                                                                                                                                                                                               // another
+                                                                                                                                                                                                               // package
+                                                       if (existingMethods == null)
+                                                               existingMethods = new MethodBinding[1];
+                                                       else
+                                                               System
+                                                                               .arraycopy(
+                                                                                               existingMethods,
+                                                                                               0,
+                                                                                               (existingMethods = new MethodBinding[existingMethods.length + 1]),
+                                                                                               0, existingMethods.length - 1);
+                                                       existingMethods[existingMethods.length - 1] = method;
+                                                       this.inheritedMethods.put(method.selector,
+                                                                       existingMethods);
+                                               } else {
+                                                       if (nonVisibleDefaultMethods == null)
+                                                               nonVisibleDefaultMethods = new MethodBinding[10];
+                                                       else if (nonVisibleCount == nonVisibleDefaultMethods.length)
+                                                               System
+                                                                               .arraycopy(
+                                                                                               nonVisibleDefaultMethods,
+                                                                                               0,
+                                                                                               (nonVisibleDefaultMethods = new MethodBinding[nonVisibleCount * 2]),
+                                                                                               0, nonVisibleCount);
+                                                       nonVisibleDefaultMethods[nonVisibleCount++] = method;
+
+                                                       if (method.isAbstract() && !this.type.isAbstract()) // non
+                                                                                                                                                               // visible
+                                                                                                                                                               // abstract
+                                                                                                                                                               // methods
+                                                                                                                                                               // cannot
+                                                                                                                                                               // be
+                                                                                                                                                               // overridden
+                                                                                                                                                               // so
+                                                                                                                                                               // the
+                                                                                                                                                               // type
+                                                                                                                                                               // must
+                                                                                                                                                               // be
+                                                                                                                                                               // defined
+                                                                                                                                                               // abstract
+                                                               this.problemReporter()
+                                                                               .abstractMethodCannotBeOverridden(
+                                                                                               this.type, method);
+
+                                                       MethodBinding[] current = (MethodBinding[]) this.currentMethods
+                                                                       .get(method.selector);
+                                                       if (current != null) { // non visible methods
+                                                                                                       // cannot be overridden so a
+                                                                                                       // warning is issued
+                                                               foundMatch: for (int i = 0, length = current.length; i < length; i++) {
+                                                                       if (method.returnType == current[i].returnType
+                                                                                       && method
+                                                                                                       .areParametersEqual(current[i])) {
+                                                                               this.problemReporter()
+                                                                                               .overridesPackageDefaultMethod(
+                                                                                                               current[i], method);
+                                                                               break foundMatch;
+                                                                       }
                                                                }
                                                        }
                                                }
                                        }
                                }
+                               superType = superType.superclass();
                        }
-                       superType = superType.superclass();
                }
-       }
 
-       for (int i = 0; i <= lastPosition; i++) {
-               ReferenceBinding[] interfaces = interfacesToVisit[i];
-               if (interfaces==null) {
-                       interfaces = new ReferenceBinding[0];
-               }
-               for (int j = 0, length = interfaces.length; j < length; j++) {
-                       superType = interfaces[j];
-                       if ((superType.tagBits & InterfaceVisited) == 0) {
-                               superType.tagBits |= InterfaceVisited;
-                               if (superType.isValidBinding()) {
-                                       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;
-                                       }
+               for (int i = 0; i <= lastPosition; i++) {
+                       ReferenceBinding[] interfaces = interfacesToVisit[i];
+                       if (interfaces == null) {
+                               interfaces = new ReferenceBinding[0];
+                       }
+                       for (int j = 0, length = interfaces.length; j < length; j++) {
+                               superType = interfaces[j];
+                               if ((superType.tagBits & InterfaceVisited) == 0) {
+                                       superType.tagBits |= InterfaceVisited;
+                                       if (superType.isValidBinding()) {
+                                               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;
+                                               }
 
-                                       MethodBinding[] methods = superType.methods();
-                                       for (int m = methods.length; --m >= 0;) { // Interface methods are all abstract public
-                                               MethodBinding method = methods[m];
-                                               MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(method.selector);
-                                               if (existingMethods == null)
-                                                       existingMethods = new MethodBinding[1];
-                                               else
-                                                       System.arraycopy(existingMethods, 0,
-                                                               (existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1);
-                                               existingMethods[existingMethods.length - 1] = method;
-                                               this.inheritedMethods.put(method.selector, existingMethods);
+                                               MethodBinding[] methods = superType.methods();
+                                               for (int m = methods.length; --m >= 0;) { // Interface
+                                                                                                                                       // methods
+                                                                                                                                       // are all
+                                                                                                                                       // abstract
+                                                                                                                                       // public
+                                                       MethodBinding method = methods[m];
+                                                       MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods
+                                                                       .get(method.selector);
+                                                       if (existingMethods == null)
+                                                               existingMethods = new MethodBinding[1];
+                                                       else
+                                                               System
+                                                                               .arraycopy(
+                                                                                               existingMethods,
+                                                                                               0,
+                                                                                               (existingMethods = new MethodBinding[existingMethods.length + 1]),
+                                                                                               0, existingMethods.length - 1);
+                                                       existingMethods[existingMethods.length - 1] = method;
+                                                       this.inheritedMethods.put(method.selector,
+                                                                       existingMethods);
+                                               }
                                        }
                                }
                        }
                }
-       }
 
-       // bit reinitialization
-       for (int i = 0; i <= lastPosition; i++) {
-               ReferenceBinding[] interfaces = interfacesToVisit[i];
-               if (interfaces==null) {
-                       interfaces = new ReferenceBinding[0];
+               // bit reinitialization
+               for (int i = 0; i <= lastPosition; i++) {
+                       ReferenceBinding[] interfaces = interfacesToVisit[i];
+                       if (interfaces == null) {
+                               interfaces = new ReferenceBinding[0];
+                       }
+                       for (int j = 0, length = interfaces.length; j < length; j++)
+                               interfaces[j].tagBits &= ~InterfaceVisited;
                }
-               for (int j = 0, length = interfaces.length; j < length; j++)
-                       interfaces[j].tagBits &= ~InterfaceVisited;
        }
-}
-private void computeMethods() {
-       MethodBinding[] methods = type.methods();
-       if (methods==null) {
-               methods = new MethodBinding[0];
-       }
-       int size = methods.length;
-       this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps method selectors to an array of methods... must search to match paramaters & return type
-       for (int m = size; --m >= 0;) {
-               MethodBinding method = methods[m];
-               if (!(method.isConstructor() || method.isDefaultAbstract())) { // keep all methods which are NOT constructors or default abstract
-                       MethodBinding[] existingMethods = (MethodBinding[]) this.currentMethods.get(method.selector);
-                       if (existingMethods == null)
-                               existingMethods = new MethodBinding[1];
-                       else
-                               System.arraycopy(existingMethods, 0,
-                                       (existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1);
-                       existingMethods[existingMethods.length - 1] = method;
-                       this.currentMethods.put(method.selector, existingMethods);
+
+       private void computeMethods() {
+               MethodBinding[] methods = type.methods();
+               if (methods == null) {
+                       methods = new MethodBinding[0];
+               }
+               int size = methods.length;
+               this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps
+                                                                                                                                                       // method
+                                                                                                                                                       // selectors
+                                                                                                                                                       // to
+                                                                                                                                                       // an
+                                                                                                                                                       // array
+                                                                                                                                                       // of
+                                                                                                                                                       // methods...
+                                                                                                                                                       // must
+                                                                                                                                                       // search
+                                                                                                                                                       // to
+                                                                                                                                                       // match
+                                                                                                                                                       // paramaters
+                                                                                                                                                       // &
+                                                                                                                                                       // return
+                                                                                                                                                       // type
+               for (int m = size; --m >= 0;) {
+                       MethodBinding method = methods[m];
+                       if (!(method.isConstructor() || method.isDefaultAbstract())) { // keep
+                                                                                                                                                       // all
+                                                                                                                                                       // methods
+                                                                                                                                                       // which
+                                                                                                                                                       // are
+                                                                                                                                                       // NOT
+                                                                                                                                                       // constructors
+                                                                                                                                                       // or
+                                                                                                                                                       // default
+                                                                                                                                                       // abstract
+                               MethodBinding[] existingMethods = (MethodBinding[]) this.currentMethods
+                                               .get(method.selector);
+                               if (existingMethods == null)
+                                       existingMethods = new MethodBinding[1];
+                               else
+                                       System
+                                                       .arraycopy(
+                                                                       existingMethods,
+                                                                       0,
+                                                                       (existingMethods = new MethodBinding[existingMethods.length + 1]),
+                                                                       0, existingMethods.length - 1);
+                               existingMethods[existingMethods.length - 1] = method;
+                               this.currentMethods.put(method.selector, existingMethods);
+                       }
                }
        }
-}
-private ReferenceBinding errorException() {
-       if (errorException == null)
-               this.errorException = this.type.scope.getJavaLangError();
-       return errorException;
-}
-private boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) {
-       if (inheritedMethod.modifiers == newMethod.modifiers) return true;
 
-       if (newMethod.isPublic()) return true;          // Covers everything
-       if (inheritedMethod.isPublic()) return false;
+       private ReferenceBinding errorException() {
+               if (errorException == null)
+                       this.errorException = this.type.scope.getJavaLangError();
+               return errorException;
+       }
 
-       if (newMethod.isProtected()) return true;
-       if (inheritedMethod.isProtected()) return false;
+       private boolean isAsVisible(MethodBinding newMethod,
+                       MethodBinding inheritedMethod) {
+               if (inheritedMethod.modifiers == newMethod.modifiers)
+                       return true;
 
-       return !newMethod.isPrivate();          // The inheritedMethod cannot be private since it would not be visible
-}
-private boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
-       do {
-               if (testClass == superclass) return true;
-       } while ((testClass = testClass.superclass()) != null);
-       return false;
-}
-private boolean mustImplementAbstractMethod(MethodBinding abstractMethod) {
-       // if the type's superclass is an abstract class, then all abstract methods must be implemented
-       // otherwise, skip it if the type's superclass must implement any of the inherited methods
-       ReferenceBinding superclass = this.type.superclass();
-       ReferenceBinding declaringClass = abstractMethod.declaringClass;
-       if (declaringClass.isClass()) {
-               while (superclass.isAbstract() && superclass != declaringClass)
-                       superclass = superclass.superclass(); // find the first concrete superclass or the abstract declaringClass
-       } else {
-               if (this.type.implementsInterface(declaringClass, false)) {
-                       if (this.type.isAbstract()) return false; // leave it for the subclasses
-                       if (!superclass.implementsInterface(declaringClass, true)) // only if a superclass does not also implement the interface
+               if (newMethod.isPublic())
+                       return true; // Covers everything
+               if (inheritedMethod.isPublic())
+                       return false;
+
+               if (newMethod.isProtected())
+                       return true;
+               if (inheritedMethod.isProtected())
+                       return false;
+
+               return !newMethod.isPrivate(); // The inheritedMethod cannot be private
+                                                                               // since it would not be visible
+       }
+
+       private boolean isSameClassOrSubclassOf(ReferenceBinding testClass,
+                       ReferenceBinding superclass) {
+               do {
+                       if (testClass == superclass)
                                return true;
+               } while ((testClass = testClass.superclass()) != null);
+               return false;
+       }
+
+       private boolean mustImplementAbstractMethod(MethodBinding abstractMethod) {
+               // if the type's superclass is an abstract class, then all abstract
+               // methods must be implemented
+               // otherwise, skip it if the type's superclass must implement any of the
+               // inherited methods
+               ReferenceBinding superclass = this.type.superclass();
+               ReferenceBinding declaringClass = abstractMethod.declaringClass;
+               if (declaringClass.isClass()) {
+                       while (superclass.isAbstract() && superclass != declaringClass)
+                               superclass = superclass.superclass(); // find the first
+                                                                                                               // concrete superclass
+                                                                                                               // or the abstract
+                                                                                                               // declaringClass
+               } else {
+                       if (this.type.implementsInterface(declaringClass, false)) {
+                               if (this.type.isAbstract())
+                                       return false; // leave it for the subclasses
+                               if (!superclass.implementsInterface(declaringClass, true)) // only
+                                                                                                                                                       // if a
+                                                                                                                                                       // superclass
+                                                                                                                                                       // does
+                                                                                                                                                       // not
+                                                                                                                                                       // also
+                                                                                                                                                       // implement
+                                                                                                                                                       // the
+                                                                                                                                                       // interface
+                                       return true;
+                       }
+                       while (superclass.isAbstract()
+                                       && !superclass.implementsInterface(declaringClass, false))
+                               superclass = superclass.superclass(); // find the first
+                                                                                                               // concrete superclass
+                                                                                                               // or the superclass
+                                                                                                               // which implements the
+                                                                                                               // interface
                }
-               while (superclass.isAbstract() && !superclass.implementsInterface(declaringClass, false))
-                       superclass = superclass.superclass(); // find the first concrete superclass or the superclass which implements the interface
+               return superclass.isAbstract(); // if it is a concrete class then we
+                                                                               // have already reported problem against
+                                                                               // it
+       }
+
+       private ProblemReporter problemReporter() {
+               return this.type.scope.problemReporter();
+       }
+
+       private ProblemReporter problemReporter(MethodBinding currentMethod) {
+               ProblemReporter reporter = problemReporter();
+               if (currentMethod.declaringClass == type) // only report against the
+                                                                                                       // currentMethod if its
+                                                                                                       // implemented by the type
+                       reporter.referenceContext = currentMethod.sourceMethod();
+               return reporter;
+       }
+
+       private ReferenceBinding runtimeException() {
+               if (runtimeException == null)
+                       this.runtimeException = this.type.scope
+                                       .getJavaLangRuntimeException();
+               return runtimeException;
+       }
+
+       public void verify(SourceTypeBinding type) {
+               this.type = type;
+               this.computeMethods();
+               this.computeInheritedMethods();
+               this.checkMethods();
+       }
+
+       public String toString() {
+               StringBuffer buffer = new StringBuffer(10);
+               buffer.append("MethodVerifier for type: "); //$NON-NLS-1$
+               buffer.append(type.readableName());
+               buffer.append('\n');
+               buffer.append("\t-inherited methods: "); //$NON-NLS-1$
+               buffer.append(this.inheritedMethods);
+               return buffer.toString();
        }
-       return superclass.isAbstract();         // if it is a concrete class then we have already reported problem against it
-}
-private ProblemReporter problemReporter() {
-       return this.type.scope.problemReporter();
-}
-private ProblemReporter problemReporter(MethodBinding currentMethod) {
-       ProblemReporter reporter = problemReporter();
-       if (currentMethod.declaringClass == type)       // only report against the currentMethod if its implemented by the type
-               reporter.referenceContext = currentMethod.sourceMethod();
-       return reporter;
-}
-private ReferenceBinding runtimeException() {
-       if (runtimeException == null)
-               this.runtimeException = this.type.scope.getJavaLangRuntimeException();
-       return runtimeException;
-}
-public void verify(SourceTypeBinding type) {
-       this.type = type;
-       this.computeMethods();
-       this.computeInheritedMethods();
-       this.checkMethods();
-}
-public String toString() {
-       StringBuffer buffer = new StringBuffer(10);
-       buffer.append("MethodVerifier for type: "); //$NON-NLS-1$
-       buffer.append(type.readableName());
-       buffer.append('\n');
-       buffer.append("\t-inherited methods: "); //$NON-NLS-1$
-       buffer.append(this.inheritedMethods);
-       return buffer.toString();
-}
 }