Example usage for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding sortMethods

List of usage examples for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding sortMethods

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding sortMethods.

Prototype

public static void sortMethods(MethodBinding[] sortedMethods, int left, int right) 

Source Link

Document

Sort the field array using a quicksort

Usage

From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

private void addDefaultAbstractMethods() {
    if ((this.tagBits & TagBits.KnowsDefaultAbstractMethods) != 0)
        return;//  w  w  w.  j  a  v  a  2 s.c  om

    this.tagBits |= TagBits.KnowsDefaultAbstractMethods;
    if (isClass() && isAbstract()) {
        if (this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2)
            return; // no longer added for post 1.2 targets

        ReferenceBinding[] itsInterfaces = superInterfaces();
        if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
            MethodBinding[] defaultAbstracts = null;
            int defaultAbstractsCount = 0;
            ReferenceBinding[] interfacesToVisit = itsInterfaces;
            int nextPosition = interfacesToVisit.length;
            for (int i = 0; i < nextPosition; i++) {
                ReferenceBinding superType = interfacesToVisit[i];
                if (superType.isValidBinding()) {
                    MethodBinding[] superMethods = superType.methods();
                    nextAbstractMethod: for (int m = superMethods.length; --m >= 0;) {
                        MethodBinding method = superMethods[m];
                        // explicitly implemented ?
                        if (implementsMethod(method))
                            continue nextAbstractMethod;
                        if (defaultAbstractsCount == 0) {
                            defaultAbstracts = new MethodBinding[5];
                        } else {
                            // already added as default abstract ?
                            for (int k = 0; k < defaultAbstractsCount; k++) {
                                MethodBinding alreadyAdded = defaultAbstracts[k];
                                if (CharOperation.equals(alreadyAdded.selector, method.selector)
                                        && alreadyAdded.areParametersEqual(method))
                                    continue nextAbstractMethod;
                            }
                        }
                        MethodBinding defaultAbstract = new MethodBinding(
                                method.modifiers | ExtraCompilerModifiers.AccDefaultAbstract
                                        | ClassFileConstants.AccSynthetic,
                                method.selector, method.returnType, method.parameters, method.thrownExceptions,
                                this);
                        if (defaultAbstractsCount == defaultAbstracts.length)
                            System.arraycopy(defaultAbstracts, 0,
                                    defaultAbstracts = new MethodBinding[2 * defaultAbstractsCount], 0,
                                    defaultAbstractsCount);
                        defaultAbstracts[defaultAbstractsCount++] = defaultAbstract;
                    }

                    if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
                        int itsLength = itsInterfaces.length;
                        if (nextPosition + itsLength >= interfacesToVisit.length)
                            System.arraycopy(interfacesToVisit, 0,
                                    interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0,
                                    nextPosition);
                        nextInterface: for (int a = 0; a < itsLength; a++) {
                            ReferenceBinding next = itsInterfaces[a];
                            for (int b = 0; b < nextPosition; b++)
                                if (next == interfacesToVisit[b])
                                    continue nextInterface;
                            interfacesToVisit[nextPosition++] = next;
                        }
                    }
                }
            }
            if (defaultAbstractsCount > 0) {
                int length = this.methods.length;
                System.arraycopy(this.methods, 0,
                        this.methods = new MethodBinding[length + defaultAbstractsCount], 0, length);
                System.arraycopy(defaultAbstracts, 0, this.methods, length, defaultAbstractsCount);
                // re-sort methods
                length = length + defaultAbstractsCount;
                if (length > 1)
                    ReferenceBinding.sortMethods(this.methods, 0, length);
                // this.tagBits |= TagBits.AreMethodsSorted; -- already set in #methods()
            }
        }
    }
}

From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
    int argCount = argumentTypes.length;
    if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
        long range;
        if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
            nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
                MethodBinding method = this.methods[imethod];
                if (method.parameters.length == argCount) {
                    TypeBinding[] toMatch = method.parameters;
                    for (int iarg = 0; iarg < argCount; iarg++)
                        if (toMatch[iarg] != argumentTypes[iarg])
                            continue nextMethod;
                    return method;
                }/*from   w w  w. jav a2s.  c o m*/
            }
        }
    } else {
        // lazily sort methods
        if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
            int length = this.methods.length;
            if (length > 1)
                ReferenceBinding.sortMethods(this.methods, 0, length);
            this.tagBits |= TagBits.AreMethodsSorted;
        }
        long range;
        if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
            nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
                MethodBinding method = this.methods[imethod];
                if (resolveTypesFor(method) == null || method.returnType == null) {
                    methods();
                    return getExactConstructor(argumentTypes); // try again since the problem methods have been removed
                }
                if (method.parameters.length == argCount) {
                    TypeBinding[] toMatch = method.parameters;
                    for (int iarg = 0; iarg < argCount; iarg++)
                        if (toMatch[iarg] != argumentTypes[iarg])
                            continue nextMethod;
                    return method;
                }
            }
        }
    }
    return null;
}

From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes,
        CompilationUnitScope refScope) {
    // sender from refScope calls recordTypeReference(this)
    int argCount = argumentTypes.length;
    boolean foundNothing = true;

    if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
        long range;
        if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
            nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
                MethodBinding method = this.methods[imethod];
                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 iarg = 0; iarg < argCount; iarg++)
                        if (toMatch[iarg] != argumentTypes[iarg])
                            continue nextMethod;
                    return method;
                }/* w  w  w .  j a  v  a  2  s .  c o  m*/
            }
        }
    } else {
        // lazily sort methods
        if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
            int length = this.methods.length;
            if (length > 1)
                ReferenceBinding.sortMethods(this.methods, 0, length);
            this.tagBits |= TagBits.AreMethodsSorted;
        }

        long range;
        if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
            // check unresolved method
            int start = (int) range, end = (int) (range >> 32);
            for (int imethod = start; imethod <= end; imethod++) {
                MethodBinding method = this.methods[imethod];
                if (resolveTypesFor(method) == null || method.returnType == null) {
                    methods();
                    return getExactMethod(selector, argumentTypes, refScope); // try again since the problem methods have been removed
                }
            }
            // check dup collisions
            boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
            for (int i = start; i <= end; i++) {
                MethodBinding method1 = this.methods[i];
                for (int j = end; j > i; j--) {
                    MethodBinding method2 = this.methods[j];
                    boolean paramsMatch = isSource15 ? method1.areParameterErasuresEqual(method2)
                            : method1.areParametersEqual(method2);
                    if (paramsMatch) {
                        methods();
                        return getExactMethod(selector, argumentTypes, refScope); // try again since the problem methods have been removed
                    }
                }
            }
            nextMethod: for (int imethod = start; imethod <= end; imethod++) {
                MethodBinding method = this.methods[imethod];
                TypeBinding[] toMatch = method.parameters;
                if (toMatch.length == argCount) {
                    for (int iarg = 0; iarg < argCount; iarg++)
                        if (toMatch[iarg] != argumentTypes[iarg])
                            continue nextMethod;
                    return method;
                }
            }
        }
    }

    if (foundNothing) {
        if (isInterface()) {
            if (this.superInterfaces.length == 1) {
                if (refScope != null)
                    refScope.recordTypeReference(this.superInterfaces[0]);
                return this.superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
            }
        } else if (this.superclass != null) {
            if (refScope != null)
                refScope.recordTypeReference(this.superclass);
            return this.superclass.getExactMethod(selector, argumentTypes, refScope);
        }
    }
    return null;
}

From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

public MethodBinding[] getMethods(char[] selector) {
    if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
        long range;
        if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
            int start = (int) range, end = (int) (range >> 32);
            int length = end - start + 1;
            MethodBinding[] result;//from  ww  w  .  j a  v  a  2  s.co m
            System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
            return result;
        } else {
            return Binding.NO_METHODS;
        }
    }
    // lazily sort methods
    if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
        int length = this.methods.length;
        if (length > 1)
            ReferenceBinding.sortMethods(this.methods, 0, length);
        this.tagBits |= TagBits.AreMethodsSorted;
    }
    MethodBinding[] result;
    long range;
    if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
        int start = (int) range, end = (int) (range >> 32);
        for (int i = start; i <= end; i++) {
            MethodBinding method = this.methods[i];
            if (resolveTypesFor(method) == null || method.returnType == null) {
                methods();
                return getMethods(selector); // try again since the problem methods have been removed
            }
        }
        int length = end - start + 1;
        System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
    } else {
        return Binding.NO_METHODS;
    }
    boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
    for (int i = 0, length = result.length - 1; i < length; i++) {
        MethodBinding method = result[i];
        for (int j = length; j > i; j--) {
            boolean paramsMatch = isSource15 ? method.areParameterErasuresEqual(result[j])
                    : method.areParametersEqual(result[j]);
            if (paramsMatch) {
                methods();
                return getMethods(selector); // try again since the duplicate methods have been removed
            }
        }
    }
    return result;
}

From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

public MethodBinding[] methods() {
    if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
        return this.methods;

    // lazily sort methods
    if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
        int length = this.methods.length;
        if (length > 1)
            ReferenceBinding.sortMethods(this.methods, 0, length);
        this.tagBits |= TagBits.AreMethodsSorted;
    }/*from   w ww.  j  a va 2  s . c  o m*/

    int failed = 0;
    MethodBinding[] resolvedMethods = this.methods;
    try {
        for (int i = 0, length = this.methods.length; i < length; i++) {
            if (resolveTypesFor(this.methods[i]) == null) {
                // do not alter original method array until resolution is over, due to reentrance (143259)
                if (resolvedMethods == this.methods) {
                    System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
                }
                resolvedMethods[i] = null; // unable to resolve parameters
                failed++;
            }
        }

        // find & report collision cases
        boolean complyTo15OrAbove = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
        boolean compliance16 = this.scope.compilerOptions().complianceLevel == ClassFileConstants.JDK1_6;

        for (int i = 0, length = this.methods.length; i < length; i++) {
            int severity = ProblemSeverities.Error;
            MethodBinding method = resolvedMethods[i];
            if (method == null)
                continue;
            char[] selector = method.selector;
            AbstractMethodDeclaration methodDecl = null;
            nextSibling: for (int j = i + 1; j < length; j++) {
                MethodBinding method2 = resolvedMethods[j];
                if (method2 == null)
                    continue nextSibling;
                if (!CharOperation.equals(selector, method2.selector))
                    break nextSibling; // methods with same selector are contiguous

                if (complyTo15OrAbove) {
                    if (method.areParameterErasuresEqual(method2)) {
                        // we now ignore return types in 1.7 when detecting duplicates, just as we did before 1.5 
                        // Only in 1.6, we have to make sure even return types are different
                        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=317719
                        if (compliance16 && method.returnType != null && method2.returnType != null) {
                            if (method.returnType.erasure() != method2.returnType.erasure()) {
                                // check to see if the erasure of either method is equal to the other
                                // if not, then change severity to WARNING
                                TypeBinding[] params1 = method.parameters;
                                TypeBinding[] params2 = method2.parameters;
                                int pLength = params1.length;
                                TypeVariableBinding[] vars = method.typeVariables;
                                TypeVariableBinding[] vars2 = method2.typeVariables;
                                boolean equalTypeVars = vars == vars2;
                                MethodBinding subMethod = method2;
                                if (!equalTypeVars) {
                                    MethodBinding temp = method.computeSubstitutedMethod(method2,
                                            this.scope.environment());
                                    if (temp != null) {
                                        equalTypeVars = true;
                                        subMethod = temp;
                                    }
                                }
                                boolean equalParams = method.areParametersEqual(subMethod);
                                if (equalParams && equalTypeVars) {
                                    // duplicates regardless of return types
                                } else if (vars != Binding.NO_TYPE_VARIABLES
                                        && vars2 != Binding.NO_TYPE_VARIABLES) {
                                    // both have type arguments. Erasure of signature of one cannot be equal to signature of other
                                    severity = ProblemSeverities.Warning;
                                } else if (pLength > 0) {
                                    int index = pLength;
                                    // is erasure of signature of m2 same as signature of m1?
                                    for (; --index >= 0;) {
                                        if (params1[index] != params2[index].erasure())
                                            break;
                                        if (params1[index] == params2[index]) {
                                            TypeBinding type = params1[index].leafComponentType();
                                            if (type instanceof SourceTypeBinding
                                                    && type.typeVariables() != Binding.NO_TYPE_VARIABLES) {
                                                index = pLength; // handle comparing identical source types like X<T>... its erasure is itself BUT we need to answer false
                                                break;
                                            }
                                        }
                                    }
                                    if (index >= 0 && index < pLength) {
                                        // is erasure of signature of m1 same as signature of m2?
                                        for (index = pLength; --index >= 0;)
                                            if (params1[index].erasure() != params2[index])
                                                break;

                                    }
                                    if (index >= 0) {
                                        // erasure of neither is equal to signature of other
                                        severity = ProblemSeverities.Warning;
                                    }
                                } else if (pLength != 0) {
                                    severity = ProblemSeverities.Warning;
                                } // pLength = 0 automatically makes erasure of arguments one equal to arguments of other.
                            }
                            // else return types also equal. All conditions satisfied
                            // to give error in 1.6 compliance as well.
                        }
                    } else {
                        continue nextSibling;
                    }
                } else if (!method.areParametersEqual(method2)) {
                    // prior to 1.5, parameters identical meant a collision case
                    continue nextSibling;
                }
                // otherwise duplicates / name clash
                boolean isEnumSpecialMethod = isEnum() && (CharOperation.equals(selector, TypeConstants.VALUEOF)
                        || CharOperation.equals(selector, TypeConstants.VALUES));
                // report duplicate
                boolean removeMethod2 = (severity == ProblemSeverities.Error) ? true : false; // do not remove if in 1.6 and just a warning given
                if (methodDecl == null) {
                    methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost & may still be null if method is special
                    if (methodDecl != null && methodDecl.binding != null) { // ensure its a valid user defined method
                        boolean removeMethod = method.returnType == null && method2.returnType != null;
                        if (isEnumSpecialMethod) {
                            this.scope.problemReporter().duplicateEnumSpecialMethod(this, methodDecl);
                            // remove user defined methods & keep the synthetic
                            removeMethod = true;
                        } else {
                            this.scope.problemReporter().duplicateMethodInType(this, methodDecl,
                                    method.areParametersEqual(method2), severity);
                        }
                        if (removeMethod) {
                            removeMethod2 = false;
                            methodDecl.binding = null;
                            // do not alter original method array until resolution is over, due to reentrance (143259)
                            if (resolvedMethods == this.methods)
                                System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length],
                                        0, length);
                            resolvedMethods[i] = null;
                            failed++;
                        }
                    }
                }
                AbstractMethodDeclaration method2Decl = method2.sourceMethod();
                if (method2Decl != null && method2Decl.binding != null) { // ensure its a valid user defined method
                    if (isEnumSpecialMethod) {
                        this.scope.problemReporter().duplicateEnumSpecialMethod(this, method2Decl);
                        removeMethod2 = true;
                    } else {
                        this.scope.problemReporter().duplicateMethodInType(this, method2Decl,
                                method.areParametersEqual(method2), severity);
                    }
                    if (removeMethod2) {
                        method2Decl.binding = null;
                        // do not alter original method array until resolution is over, due to reentrance (143259)
                        if (resolvedMethods == this.methods)
                            System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0,
                                    length);
                        resolvedMethods[j] = null;
                        failed++;
                    }
                }
            }
            if (method.returnType == null && resolvedMethods[i] != null) { // forget method with invalid return type... was kept to detect possible collisions
                methodDecl = method.sourceMethod();
                if (methodDecl != null)
                    methodDecl.binding = null;
                // do not alter original method array until resolution is over, due to reentrance (143259)
                if (resolvedMethods == this.methods)
                    System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
                resolvedMethods[i] = null;
                failed++;
            }
        }
    } finally {
        if (failed > 0) {
            int newSize = resolvedMethods.length - failed;
            if (newSize == 0) {
                this.methods = Binding.NO_METHODS;
            } else {
                MethodBinding[] newMethods = new MethodBinding[newSize];
                for (int i = 0, j = 0, length = resolvedMethods.length; i < length; i++)
                    if (resolvedMethods[i] != null)
                        newMethods[j++] = resolvedMethods[i];
                this.methods = newMethods;
            }
        }

        // handle forward references to potential default abstract methods
        addDefaultAbstractMethods();
        this.tagBits |= TagBits.AreMethodsComplete;
    }
    return this.methods;
}