List of usage examples for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding sortMethods
public static void sortMethods(MethodBinding[] sortedMethods, int left, int right)
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; }