List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding findSuperTypeOriginatingFrom
public TypeBinding findSuperTypeOriginatingFrom(TypeBinding otherType)
From source file:org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.java
License:Open Source License
/** * Answer true if the receiver is visible to the receiverType and the invocationType. *//*from w ww.j ava 2 s .co m*/ public final boolean canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType) { if (isPublic()) return true; if (invocationType == this && invocationType == receiverType) return true; if (isProtected()) { // answer true if the invocationType is the declaringClass or they are in the same package // OR the invocationType is a subclass of the declaringClass // AND the invocationType is the invocationType or its subclass // OR the type is a static method accessed directly through a type // OR previous assertions are true for one of the enclosing type if (invocationType == this) return true; if (invocationType.fPackage == this.fPackage) return true; TypeBinding currentType = invocationType.erasure(); TypeBinding declaringClass = enclosingType().erasure(); // protected types always have an enclosing one if (declaringClass == invocationType) return true; if (declaringClass == null) return false; // could be null if incorrect top-level protected type //int depth = 0; do { if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true; //depth++; currentType = currentType.enclosingType(); } while (currentType != null); return false; } if (isPrivate()) { // answer true if the receiverType is the receiver or its enclosingType // AND the invocationType and the receiver have a common enclosingType receiverCheck: { if (!(receiverType == this || receiverType == enclosingType())) { // special tolerance for type variable direct bounds, but only if compliance <= 1.6, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622 if (receiverType.isTypeVariable()) { TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType; if (typeVariable.environment.globalOptions.complianceLevel <= ClassFileConstants.JDK1_6 && (typeVariable.isErasureBoundTo(erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure()))) break receiverCheck; } return false; } } if (invocationType != this) { ReferenceBinding outerInvocationType = invocationType; ReferenceBinding temp = outerInvocationType.enclosingType(); while (temp != null) { outerInvocationType = temp; temp = temp.enclosingType(); } ReferenceBinding outerDeclaringClass = (ReferenceBinding) erasure(); temp = outerDeclaringClass.enclosingType(); while (temp != null) { outerDeclaringClass = temp; temp = temp.enclosingType(); } if (outerInvocationType != outerDeclaringClass) return false; } return true; } // isDefault() if (invocationType.fPackage != this.fPackage) return false; ReferenceBinding currentType = receiverType; TypeBinding originalDeclaringClass = (enclosingType() == null ? this : enclosingType()).original(); do { if (currentType.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002 if (originalDeclaringClass == currentType.erasure().original()) return true; } else { if (originalDeclaringClass == currentType.original()) return true; } PackageBinding currentPackage = currentType.fPackage; // package could be null for wildcards/intersection types, ignore and recurse in superclass if (currentPackage != null && currentPackage != this.fPackage) return false; } while ((currentType = currentType.superclass()) != null); return false; }
From source file:org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.java
License:Open Source License
/** * Answer true if the receiver is visible to the type provided by the scope. *//*from ww w . j a v a 2 s. c o m*/ public final boolean canBeSeenBy(Scope scope) { // GROOVY start if (scope.compilationUnitScope() != null && scope.compilationUnitScope().canSeeEverything()) { return true; } // GROOVY end if (isPublic()) return true; SourceTypeBinding invocationType = scope.enclosingSourceType(); if (invocationType == this) return true; if (invocationType == null) // static import call return !isPrivate() && scope.getCurrentPackage() == this.fPackage; if (isProtected()) { // answer true if the invocationType is the declaringClass or they are in the same package // OR the invocationType is a subclass of the declaringClass // AND the invocationType is the invocationType or its subclass // OR the type is a static method accessed directly through a type // OR previous assertions are true for one of the enclosing type if (invocationType.fPackage == this.fPackage) return true; TypeBinding declaringClass = enclosingType(); // protected types always have an enclosing one if (declaringClass == null) return false; // could be null if incorrect top-level protected type declaringClass = declaringClass.erasure();// erasure cannot be null TypeBinding currentType = invocationType.erasure(); // int depth = 0; do { if (declaringClass == invocationType) return true; if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true; // depth++; currentType = currentType.enclosingType(); } while (currentType != null); return false; } if (isPrivate()) { // answer true if the receiver and the invocationType have a common enclosingType // already know they are not the identical type ReferenceBinding outerInvocationType = invocationType; ReferenceBinding temp = outerInvocationType.enclosingType(); while (temp != null) { outerInvocationType = temp; temp = temp.enclosingType(); } ReferenceBinding outerDeclaringClass = (ReferenceBinding) erasure(); temp = outerDeclaringClass.enclosingType(); while (temp != null) { outerDeclaringClass = temp; temp = temp.enclosingType(); } return outerInvocationType == outerDeclaringClass; } // isDefault() return invocationType.fPackage == this.fPackage; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
protected boolean isAcceptableMethod(MethodBinding one, MethodBinding two) { TypeBinding[] oneParams = one.parameters; TypeBinding[] twoParams = two.parameters; int oneParamsLength = oneParams.length; int twoParamsLength = twoParams.length; if (oneParamsLength == twoParamsLength) { /* Below 1.5, discard any generics we have left in for the method verifier's benefit, (so it can detect method overriding properly in the presence of generic super types.) This is so as to allow us to determine whether we have been handed an acceptable method in 1.4 terms without all the 1.5isms below kicking in and spoiling the party. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=331446 *//*from ww w . jav a2 s . com*/ boolean applyErasure = environment().globalOptions.sourceLevel < ClassFileConstants.JDK1_5; next: for (int i = 0; i < oneParamsLength; i++) { TypeBinding oneParam = applyErasure ? oneParams[i].erasure() : oneParams[i]; TypeBinding twoParam = applyErasure ? twoParams[i].erasure() : twoParams[i]; if (oneParam == twoParam || oneParam.isCompatibleWith(twoParam)) { if (two.declaringClass.isRawType()) continue next; TypeBinding leafComponentType = two.original().parameters[i].leafComponentType(); TypeBinding originalTwoParam = applyErasure ? leafComponentType.erasure() : leafComponentType; switch (originalTwoParam.kind()) { case Binding.TYPE_PARAMETER: if (((TypeVariableBinding) originalTwoParam).hasOnlyRawBounds()) continue next; //$FALL-THROUGH$ case Binding.WILDCARD_TYPE: case Binding.INTERSECTION_TYPE: case Binding.PARAMETERIZED_TYPE: TypeBinding originalOneParam = one.original().parameters[i].leafComponentType(); switch (originalOneParam.kind()) { case Binding.TYPE: case Binding.GENERIC_TYPE: TypeBinding inheritedTwoParam = oneParam.findSuperTypeOriginatingFrom(twoParam); if (inheritedTwoParam == null || !inheritedTwoParam.leafComponentType().isRawType()) break; return false; case Binding.TYPE_PARAMETER: if (!((TypeVariableBinding) originalOneParam).upperBound().isRawType()) break; return false; case Binding.RAW_TYPE: // originalOneParam is RAW so it cannot be more specific than a wildcard or parameterized type return false; } } } else { if (i == oneParamsLength - 1 && one.isVarargs() && two.isVarargs()) { TypeBinding eType = ((ArrayBinding) twoParam).elementsType(); if (oneParam == eType || oneParam.isCompatibleWith(eType)) return true; // special case to choose between 2 varargs methods when the last arg is Object[] } return false; } } return true; } if (one.isVarargs() && two.isVarargs()) { if (oneParamsLength > twoParamsLength) { // special case when autoboxing makes (int, int...) better than (Object...) but not (int...) or (Integer, int...) if (((ArrayBinding) twoParams[twoParamsLength - 1]).elementsType().id != TypeIds.T_JavaLangObject) return false; } // check that each parameter before the vararg parameters are compatible (no autoboxing allowed here) for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--) if (oneParams[i] != twoParams[i] && !oneParams[i].isCompatibleWith(twoParams[i])) return false; if (parameterCompatibilityLevel(one, twoParams) == NOT_COMPATIBLE && parameterCompatibilityLevel(two, oneParams) == VARARGS_COMPATIBLE) return true; } return false; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
/** * Returns the most specific set of types compatible with all given types. * (i.e. most specific common super types) * If no types is given, will return an empty array. If not compatible * reference type is found, returns null. In other cases, will return an array * of minimal erased types, where some nulls may appear (and must simply be * ignored).//from w w w.j av a 2 s . c om */ protected TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) { int length = types.length; int indexOfFirst = -1, actualLength = 0; for (int i = 0; i < length; i++) { TypeBinding type = types[i]; if (type == null) continue; if (type.isBaseType()) return null; if (indexOfFirst < 0) indexOfFirst = i; actualLength++; } switch (actualLength) { case 0: return Binding.NO_TYPES; case 1: return types; } TypeBinding firstType = types[indexOfFirst]; if (firstType.isBaseType()) return null; // record all supertypes of type // intersect with all supertypes of otherType ArrayList typesToVisit = new ArrayList(5); int dim = firstType.dimensions(); TypeBinding leafType = firstType.leafComponentType(); // do not allow type variables/intersection types to match with erasures for free TypeBinding firstErasure; switch (leafType.kind()) { case Binding.PARAMETERIZED_TYPE: case Binding.RAW_TYPE: case Binding.ARRAY_TYPE: firstErasure = firstType.erasure(); break; default: firstErasure = firstType; break; } if (firstErasure != firstType) { allInvocations.put(firstErasure, firstType); } typesToVisit.add(firstType); int max = 1; ReferenceBinding currentType; for (int i = 0; i < max; i++) { TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i); dim = typeToVisit.dimensions(); if (dim > 0) { leafType = typeToVisit.leafComponentType(); switch (leafType.id) { case TypeIds.T_JavaLangObject: if (dim > 1) { // Object[][] supertype is Object[] TypeBinding elementType = ((ArrayBinding) typeToVisit).elementsType(); if (!typesToVisit.contains(elementType)) { typesToVisit.add(elementType); max++; } continue; } //$FALL-THROUGH$ case TypeIds.T_byte: case TypeIds.T_short: case TypeIds.T_char: case TypeIds.T_boolean: case TypeIds.T_int: case TypeIds.T_long: case TypeIds.T_float: case TypeIds.T_double: TypeBinding superType = getJavaIoSerializable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangCloneable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangObject(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } continue; default: } typeToVisit = leafType; } currentType = (ReferenceBinding) typeToVisit; if (currentType.isCapture()) { TypeBinding firstBound = ((CaptureBinding) currentType).firstBound; if (firstBound != null && firstBound.isArrayType()) { TypeBinding superType = dim == 0 ? firstBound : (TypeBinding) environment().createArrayType(firstBound, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (firstBound.isTypeVariable() || firstBound.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } continue; } } // inject super interfaces prior to superclass ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (itsInterfaces != null) { // can be null during code assist operations that use LookupEnvironment.completeTypeBindings(parsedUnit, buildFieldsAndMethods) for (int j = 0, count = itsInterfaces.length; j < count; j++) { TypeBinding itsInterface = itsInterfaces[j]; TypeBinding superType = dim == 0 ? itsInterface : (TypeBinding) environment().createArrayType(itsInterface, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsInterface.isTypeVariable() || itsInterface.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } TypeBinding itsSuperclass = currentType.superclass(); if (itsSuperclass != null) { TypeBinding superType = dim == 0 ? itsSuperclass : (TypeBinding) environment().createArrayType(itsSuperclass, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsSuperclass.isTypeVariable() || itsSuperclass.isWildcard() /*&& !itsSuperclass.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } int superLength = typesToVisit.size(); TypeBinding[] erasedSuperTypes = new TypeBinding[superLength]; int rank = 0; for (Iterator iter = typesToVisit.iterator(); iter.hasNext();) { TypeBinding type = (TypeBinding) iter.next(); leafType = type.leafComponentType(); erasedSuperTypes[rank++] = (leafType.isTypeVariable() || leafType.isWildcard() /*&& !leafType.isCapture()*/) ? type : type.erasure(); } // intersecting first type supertypes with other types' ones, nullifying non matching supertypes int remaining = superLength; nextOtherType: for (int i = indexOfFirst + 1; i < length; i++) { TypeBinding otherType = types[i]; if (otherType == null) continue nextOtherType; if (otherType.isArrayType()) { nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType; TypeBinding match; if ((match = otherType.findSuperTypeOriginatingFrom(erasedSuperType)) == null) { erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } continue nextOtherType; } nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null) continue nextSuperType; TypeBinding match; if (erasedSuperType == otherType || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) { match = erasedSuperType; } else { if (erasedSuperType.isArrayType()) { match = null; } else { match = otherType.findSuperTypeOriginatingFrom(erasedSuperType); } if (match == null) { // incompatible super type erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } } // eliminate non minimal super types if (remaining > 1) { nextType: for (int i = 0; i < superLength; i++) { TypeBinding erasedSuperType = erasedSuperTypes[i]; if (erasedSuperType == null) continue nextType; nextOtherType: for (int j = 0; j < superLength; j++) { if (i == j) continue nextOtherType; TypeBinding otherType = erasedSuperTypes[j]; if (otherType == null) continue nextOtherType; if (erasedSuperType instanceof ReferenceBinding) { if (otherType.id == TypeIds.T_JavaLangObject && erasedSuperType.isInterface()) continue nextOtherType; // keep Object for an interface if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } else if (erasedSuperType.isArrayType()) { if (otherType.isArrayType() // keep Object[...] for an interface array (same dimensions) && otherType.leafComponentType().id == TypeIds.T_JavaLangObject && otherType.dimensions() == erasedSuperType.dimensions() && erasedSuperType.leafComponentType().isInterface()) continue nextOtherType; if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } } } } return erasedSuperTypes; }