Example usage for org.eclipse.jdt.internal.compiler.lookup TypeBinding isInterface

List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding isInterface

Introduction

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

Prototype

public boolean isInterface() 

Source Link

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.TypeDeclarationLocator.java

License:Open Source License

public int resolveLevel(Binding binding) {
    if (binding == null)
        return INACCURATE_MATCH;
    if (!(binding instanceof TypeBinding))
        return IMPOSSIBLE_MATCH;

    TypeBinding type = (TypeBinding) binding;

    switch (this.pattern.typeSuffix) {
    case CLASS_SUFFIX:
        if (!type.isClass())
            return IMPOSSIBLE_MATCH;
        break;/*from w  ww. j a  v a2s.  com*/
    case CLASS_AND_INTERFACE_SUFFIX:
        if (!(type.isClass() || (type.isInterface() && !type.isAnnotationType())))
            return IMPOSSIBLE_MATCH;
        break;
    case CLASS_AND_ENUM_SUFFIX:
        if (!(type.isClass() || type.isEnum()))
            return IMPOSSIBLE_MATCH;
        break;
    case INTERFACE_SUFFIX:
        if (!type.isInterface() || type.isAnnotationType())
            return IMPOSSIBLE_MATCH;
        break;
    case INTERFACE_AND_ANNOTATION_SUFFIX:
        if (!(type.isInterface() || type.isAnnotationType()))
            return IMPOSSIBLE_MATCH;
        break;
    case ENUM_SUFFIX:
        if (!type.isEnum())
            return IMPOSSIBLE_MATCH;
        break;
    case ANNOTATION_TYPE_SUFFIX:
        if (!type.isAnnotationType())
            return IMPOSSIBLE_MATCH;
        break;
    case TYPE_SUFFIX: // nothing
    }

    // fully qualified name
    if (this.pattern instanceof QualifiedTypeDeclarationPattern) {
        QualifiedTypeDeclarationPattern qualifiedPattern = (QualifiedTypeDeclarationPattern) this.pattern;
        return resolveLevelForType(qualifiedPattern.simpleName, qualifiedPattern.qualification, type);
    } else {
        char[] enclosingTypeName = this.pattern.enclosingTypeNames == null ? null
                : CharOperation.concatWith(this.pattern.enclosingTypeNames, '.');
        return resolveLevelForType(this.pattern.simpleName, this.pattern.pkg, enclosingTypeName, type);
    }
}

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.TypeReferenceLocator.java

License:Open Source License

protected int resolveLevelForType(TypeBinding typeBinding) {
    if (typeBinding == null || !typeBinding.isValidBinding()) {
        if (this.pattern.typeSuffix != TYPE_SUFFIX)
            return INACCURATE_MATCH;
    } else {//from   www  . j  a v a 2 s .  c o m
        switch (this.pattern.typeSuffix) {
        case CLASS_SUFFIX:
            if (!typeBinding.isClass())
                return IMPOSSIBLE_MATCH;
            break;
        case CLASS_AND_INTERFACE_SUFFIX:
            if (!(typeBinding.isClass() || (typeBinding.isInterface() && !typeBinding.isAnnotationType())))
                return IMPOSSIBLE_MATCH;
            break;
        case CLASS_AND_ENUM_SUFFIX:
            if (!(typeBinding.isClass() || typeBinding.isEnum()))
                return IMPOSSIBLE_MATCH;
            break;
        case INTERFACE_SUFFIX:
            if (!typeBinding.isInterface() || typeBinding.isAnnotationType())
                return IMPOSSIBLE_MATCH;
            break;
        case INTERFACE_AND_ANNOTATION_SUFFIX:
            if (!(typeBinding.isInterface() || typeBinding.isAnnotationType()))
                return IMPOSSIBLE_MATCH;
            break;
        case ENUM_SUFFIX:
            if (!typeBinding.isEnum())
                return IMPOSSIBLE_MATCH;
            break;
        case ANNOTATION_TYPE_SUFFIX:
            if (!typeBinding.isAnnotationType())
                return IMPOSSIBLE_MATCH;
            break;
        case TYPE_SUFFIX: // nothing
        }
    }
    return resolveLevelForType(this.pattern.simpleName, this.pattern.qualification,
            this.pattern.getTypeArguments(), 0, typeBinding);
}

From source file:lombok.eclipse.handlers.HandleListenerSupport.java

License:Open Source License

@Override
public void handle(final AnnotationValues<ListenerSupport> annotation, final Annotation source,
        final EclipseNode annotationNode) {
    EclipseType type = EclipseType.typeOf(annotationNode, source);
    if (type.isAnnotation() || type.isInterface()) {
        annotationNode.addError(canBeUsedOnClassAndEnumOnly(ListenerSupport.class));
        return;//from  w ww  . j  a v a2 s .c  om
    }

    List<Object> listenerInterfaces = annotation.getActualExpressions("value");
    if (listenerInterfaces.isEmpty()) {
        annotationNode.addError(String.format("@%s has no effect since no interface types were specified.",
                ListenerSupport.class.getName()));
        return;
    }
    for (Object listenerInterface : listenerInterfaces) {
        if (listenerInterface instanceof ClassLiteralAccess) {
            TypeBinding binding = ((ClassLiteralAccess) listenerInterface).type
                    .resolveType(type.get().initializerScope);
            if (binding == null)
                continue;
            if (!binding.isInterface()) {
                annotationNode.addWarning(String.format("@%s works only with interfaces. %s was skipped",
                        ListenerSupport.class.getName(), As.string(binding.readableName())));
                continue;
            }
            handler.addListenerField(type, binding);
            handler.addAddListenerMethod(type, binding);
            handler.addRemoveListenerMethod(type, binding);
            addFireListenerMethods(type, binding);
        }
    }

    type.editor().rebuild();
}

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

License:Open Source License

/**
 * Connect type variable supertypes, and returns true if no problem was detected
 * @param typeParameters/*from   ww  w.j  ava 2 s . c o  m*/
 * @param checkForErasedCandidateCollisions
 */
protected boolean connectTypeVariables(TypeParameter[] typeParameters,
        boolean checkForErasedCandidateCollisions) {
    /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 - We used to not bother with connecting
       type variables if source level is < 1.5. This creates problems in the reconciler if a 1.4
       project references the generified API of a 1.5 project. The "current" project's source
       level cannot decide this question for some other project. Now, if we see type parameters
       at all, we assume that the concerned java element has some legitimate business with them.
     */
    if (typeParameters == null || typeParameters.length == 0)
        return true;
    Map invocations = new HashMap(2);
    boolean noProblems = true;
    // preinitializing each type variable
    for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
        TypeParameter typeParameter = typeParameters[i];
        TypeVariableBinding typeVariable = typeParameter.binding;
        if (typeVariable == null)
            return false;

        typeVariable.superclass = getJavaLangObject();
        typeVariable.superInterfaces = Binding.NO_SUPERINTERFACES;
        // set firstBound to the binding of the first explicit bound in parameter declaration
        typeVariable.firstBound = null; // first bound used to compute erasure
    }
    nextVariable: for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
        TypeParameter typeParameter = typeParameters[i];
        TypeVariableBinding typeVariable = typeParameter.binding;
        TypeReference typeRef = typeParameter.type;
        if (typeRef == null)
            continue nextVariable;
        boolean isFirstBoundTypeVariable = false;
        TypeBinding superType = this.kind == METHOD_SCOPE
                ? typeRef.resolveType((BlockScope) this, false/*no bound check*/)
                : typeRef.resolveType((ClassScope) this);
        if (superType == null) {
            typeVariable.tagBits |= TagBits.HierarchyHasProblems;
        } else {
            typeRef.resolvedType = superType; // hold onto the problem type
            firstBound: {
                switch (superType.kind()) {
                case Binding.ARRAY_TYPE:
                    problemReporter().boundCannotBeArray(typeRef, superType);
                    typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                    break firstBound; // do not keep first bound
                case Binding.TYPE_PARAMETER:
                    isFirstBoundTypeVariable = true;
                    TypeVariableBinding varSuperType = (TypeVariableBinding) superType;
                    if (varSuperType.rank >= typeVariable.rank
                            && varSuperType.declaringElement == typeVariable.declaringElement) {
                        if (compilerOptions().complianceLevel <= ClassFileConstants.JDK1_6) {
                            problemReporter().forwardTypeVariableReference(typeParameter, varSuperType);
                            typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                            break firstBound; // do not keep first bound
                        }
                    }
                    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=335751
                    if (compilerOptions().complianceLevel > ClassFileConstants.JDK1_6) {
                        if (typeVariable.rank >= varSuperType.rank
                                && varSuperType.declaringElement == typeVariable.declaringElement) {
                            SimpleSet set = new SimpleSet(typeParameters.length);
                            set.add(typeVariable);
                            ReferenceBinding superBinding = varSuperType;
                            while (superBinding instanceof TypeVariableBinding) {
                                if (set.includes(superBinding)) {
                                    problemReporter().hierarchyCircularity(typeVariable, varSuperType, typeRef);
                                    typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                                    break firstBound; // do not keep first bound
                                } else {
                                    set.add(superBinding);
                                    superBinding = ((TypeVariableBinding) superBinding).superclass;
                                }
                            }
                        }
                    }
                    break;
                default:
                    if (((ReferenceBinding) superType).isFinal()) {
                        problemReporter().finalVariableBound(typeVariable, typeRef);
                    }
                    break;
                }
                ReferenceBinding superRefType = (ReferenceBinding) superType;
                if (!superType.isInterface()) {
                    typeVariable.superclass = superRefType;
                } else {
                    typeVariable.superInterfaces = new ReferenceBinding[] { superRefType };
                }
                typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences;
                typeVariable.firstBound = superRefType; // first bound used to compute erasure
            }
        }
        TypeReference[] boundRefs = typeParameter.bounds;
        if (boundRefs != null) {
            nextBound: for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
                typeRef = boundRefs[j];
                superType = this.kind == METHOD_SCOPE ? typeRef.resolveType((BlockScope) this, false)
                        : typeRef.resolveType((ClassScope) this);
                if (superType == null) {
                    typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                    continue nextBound;
                } else {
                    typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences;
                    boolean didAlreadyComplain = !typeRef.resolvedType.isValidBinding();
                    if (isFirstBoundTypeVariable && j == 0) {
                        problemReporter().noAdditionalBoundAfterTypeVariable(typeRef);
                        typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                        didAlreadyComplain = true;
                        //continue nextBound; - keep these bounds to minimize secondary errors
                    } else if (superType.isArrayType()) {
                        if (!didAlreadyComplain) {
                            problemReporter().boundCannotBeArray(typeRef, superType);
                            typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                        }
                        continue nextBound;
                    } else {
                        if (!superType.isInterface()) {
                            if (!didAlreadyComplain) {
                                problemReporter().boundMustBeAnInterface(typeRef, superType);
                                typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                            }
                            continue nextBound;
                        }
                    }
                    // check against superclass
                    if (checkForErasedCandidateCollisions
                            && typeVariable.firstBound == typeVariable.superclass) {
                        if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations,
                                typeVariable, typeRef)) {
                            continue nextBound;
                        }
                    }
                    // check against superinterfaces
                    ReferenceBinding superRefType = (ReferenceBinding) superType;
                    for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
                        ReferenceBinding previousInterface = typeVariable.superInterfaces[index];
                        if (previousInterface == superRefType) {
                            problemReporter().duplicateBounds(typeRef, superType);
                            typeVariable.tagBits |= TagBits.HierarchyHasProblems;
                            continue nextBound;
                        }
                        if (checkForErasedCandidateCollisions) {
                            if (hasErasedCandidatesCollisions(superType, previousInterface, invocations,
                                    typeVariable, typeRef)) {
                                continue nextBound;
                            }
                        }
                    }
                    int size = typeVariable.superInterfaces.length;
                    System.arraycopy(typeVariable.superInterfaces, 0,
                            typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size);
                    typeVariable.superInterfaces[size] = superRefType;
                }
            }
        }
        noProblems &= (typeVariable.tagBits & TagBits.HierarchyHasProblems) == 0;
    }
    return noProblems;
}

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

License:Open Source License

private TypeBinding lowerUpperBound(TypeBinding[] types, List lubStack) {

    int typeLength = types.length;
    if (typeLength == 1) {
        TypeBinding type = types[0];//ww  w . java 2 s . c  o m
        return type == null ? TypeBinding.VOID : type;
    }
    // cycle detection
    int stackLength = lubStack.size();
    nextLubCheck: for (int i = 0; i < stackLength; i++) {
        TypeBinding[] lubTypes = (TypeBinding[]) lubStack.get(i);
        int lubTypeLength = lubTypes.length;
        if (lubTypeLength < typeLength)
            continue nextLubCheck;
        nextTypeCheck: for (int j = 0; j < typeLength; j++) {
            TypeBinding type = types[j];
            if (type == null)
                continue nextTypeCheck; // ignore
            for (int k = 0; k < lubTypeLength; k++) {
                TypeBinding lubType = lubTypes[k];
                if (lubType == null)
                    continue; // ignore
                if (lubType == type || lubType.isEquivalentTo(type))
                    continue nextTypeCheck; // type found, jump to next one
            }
            continue nextLubCheck; // type not found in current lubTypes
        }
        // all types are included in some lub, cycle detected - stop recursion by answering special value (int)
        return TypeBinding.INT;
    }

    lubStack.add(types);
    Map invocations = new HashMap(1);
    TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
    if (mecs == null)
        return null;
    int length = mecs.length;
    if (length == 0)
        return TypeBinding.VOID;
    int count = 0;
    TypeBinding firstBound = null;
    int commonDim = -1;
    for (int i = 0; i < length; i++) {
        TypeBinding mec = mecs[i];
        if (mec == null)
            continue;
        mec = leastContainingInvocation(mec, invocations.get(mec), lubStack);
        if (mec == null)
            return null;
        int dim = mec.dimensions();
        if (commonDim == -1) {
            commonDim = dim;
        } else if (dim != commonDim) { // not all types have same dimension
            return null;
        }
        if (firstBound == null && !mec.leafComponentType().isInterface())
            firstBound = mec.leafComponentType();
        mecs[count++] = mec; // recompact them to the front
    }
    switch (count) {
    case 0:
        return TypeBinding.VOID;
    case 1:
        return mecs[0];
    case 2:
        if ((commonDim == 0 ? mecs[1].id : mecs[1].leafComponentType().id) == TypeIds.T_JavaLangObject)
            return mecs[0];
        if ((commonDim == 0 ? mecs[0].id : mecs[0].leafComponentType().id) == TypeIds.T_JavaLangObject)
            return mecs[1];
    }
    TypeBinding[] otherBounds = new TypeBinding[count - 1];
    int rank = 0;
    for (int i = 0; i < count; i++) {
        TypeBinding mec = commonDim == 0 ? mecs[i] : mecs[i].leafComponentType();
        if (mec.isInterface()) {
            otherBounds[rank++] = mec;
        }
    }
    TypeBinding intersectionType = environment().createWildcard(null, 0, firstBound, otherBounds,
            Wildcard.EXTENDS);
    return commonDim == 0 ? intersectionType : environment().createArrayType(intersectionType, commonDim);
}

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)./* w  w w .ja va 2s  . co  m*/
 */
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;
}

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

License:Open Source License

public MethodBinding getStaticFactory(ReferenceBinding allocationType, ReferenceBinding originalEnclosingType,
        TypeBinding[] argumentTypes, final InvocationSite allocationSite) {
    TypeVariableBinding[] classTypeVariables = allocationType.typeVariables();
    int classTypeVariablesArity = classTypeVariables.length;
    MethodBinding[] methods = allocationType.getMethods(TypeConstants.INIT, argumentTypes.length);
    MethodBinding[] staticFactories = new MethodBinding[methods.length];
    int sfi = 0;//  w w w .jav a2  s. com
    for (int i = 0, length = methods.length; i < length; i++) {
        MethodBinding method = methods[i];
        int paramLength = method.parameters.length;
        boolean isVarArgs = method.isVarargs();
        if (argumentTypes.length != paramLength)
            if (!isVarArgs || argumentTypes.length < paramLength - 1)
                continue; // incompatible
        TypeVariableBinding[] methodTypeVariables = method.typeVariables();
        int methodTypeVariablesArity = methodTypeVariables.length;

        MethodBinding staticFactory = new MethodBinding(method.modifiers | ClassFileConstants.AccStatic,
                TypeConstants.SYNTHETIC_STATIC_FACTORY, null, null, null, method.declaringClass);
        staticFactory.typeVariables = new TypeVariableBinding[classTypeVariablesArity
                + methodTypeVariablesArity];
        final SimpleLookupTable map = new SimpleLookupTable(classTypeVariablesArity + methodTypeVariablesArity);
        // Rename each type variable T of the type to T'
        final LookupEnvironment environment = environment();
        for (int j = 0; j < classTypeVariablesArity; j++) {
            map.put(classTypeVariables[j],
                    staticFactory.typeVariables[j] = new TypeVariableBinding(
                            CharOperation.concat(classTypeVariables[j].sourceName, "'".toCharArray()), //$NON-NLS-1$
                            staticFactory, j, environment));
        }
        // Rename each type variable U of method U to U''.
        for (int j = classTypeVariablesArity, max = classTypeVariablesArity
                + methodTypeVariablesArity; j < max; j++) {
            map.put(methodTypeVariables[j - classTypeVariablesArity],
                    (staticFactory.typeVariables[j] = new TypeVariableBinding(
                            CharOperation.concat(methodTypeVariables[j - classTypeVariablesArity].sourceName,
                                    "''".toCharArray()), //$NON-NLS-1$
                            staticFactory, j, environment)));
        }
        ReferenceBinding enclosingType = originalEnclosingType;
        while (enclosingType != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=345968
            if (enclosingType.kind() == Binding.PARAMETERIZED_TYPE) {
                final ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) enclosingType;
                final ReferenceBinding genericType = parameterizedType.genericType();
                TypeVariableBinding[] enclosingClassTypeVariables = genericType.typeVariables();
                int enclosingClassTypeVariablesArity = enclosingClassTypeVariables.length;
                for (int j = 0; j < enclosingClassTypeVariablesArity; j++) {
                    map.put(enclosingClassTypeVariables[j], parameterizedType.arguments[j]);
                }
            }
            enclosingType = enclosingType.enclosingType();
        }
        final Scope scope = this;
        Substitution substitution = new Substitution() {
            public LookupEnvironment environment() {
                return scope.environment();
            }

            public boolean isRawSubstitution() {
                return false;
            }

            public TypeBinding substitute(TypeVariableBinding typeVariable) {
                TypeBinding retVal = (TypeBinding) map.get(typeVariable);
                return retVal != null ? retVal : typeVariable;
            }
        };

        // initialize new variable bounds
        for (int j = 0, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) {
            TypeVariableBinding originalVariable = j < classTypeVariablesArity ? classTypeVariables[j]
                    : methodTypeVariables[j - classTypeVariablesArity];
            TypeBinding substitutedType = (TypeBinding) map.get(originalVariable);
            if (substitutedType instanceof TypeVariableBinding) {
                TypeVariableBinding substitutedVariable = (TypeVariableBinding) substitutedType;
                TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
                ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution,
                        originalVariable.superInterfaces);
                if (originalVariable.firstBound != null) {
                    substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
                            ? substitutedSuperclass // could be array type or interface
                            : substitutedInterfaces[0];
                }
                switch (substitutedSuperclass.kind()) {
                case Binding.ARRAY_TYPE:
                    substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT,
                            null);
                    substitutedVariable.superInterfaces = substitutedInterfaces;
                    break;
                default:
                    if (substitutedSuperclass.isInterface()) {
                        substitutedVariable.superclass = environment
                                .getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
                        int interfaceCount = substitutedInterfaces.length;
                        System.arraycopy(substitutedInterfaces, 0,
                                substitutedInterfaces = new ReferenceBinding[interfaceCount + 1], 1,
                                interfaceCount);
                        substitutedInterfaces[0] = (ReferenceBinding) substitutedSuperclass;
                        substitutedVariable.superInterfaces = substitutedInterfaces;
                    } else {
                        substitutedVariable.superclass = (ReferenceBinding) substitutedSuperclass; // typeVar was extending other typeVar which got substituted with interface
                        substitutedVariable.superInterfaces = substitutedInterfaces;
                    }
                }
            }
        }
        TypeVariableBinding[] returnTypeParameters = new TypeVariableBinding[classTypeVariablesArity];
        for (int j = 0; j < classTypeVariablesArity; j++) {
            returnTypeParameters[j] = (TypeVariableBinding) map.get(classTypeVariables[j]);
        }
        staticFactory.returnType = environment.createParameterizedType(allocationType, returnTypeParameters,
                allocationType.enclosingType());
        staticFactory.parameters = Scope.substitute(substitution, method.parameters);
        staticFactory.thrownExceptions = Scope.substitute(substitution, method.thrownExceptions);
        if (staticFactory.thrownExceptions == null) {
            staticFactory.thrownExceptions = Binding.NO_EXCEPTIONS;
        }
        staticFactories[sfi++] = new ParameterizedMethodBinding(
                (ParameterizedTypeBinding) environment.convertToParameterizedType(staticFactory.declaringClass),
                staticFactory);
    }
    if (sfi == 0)
        return null;
    if (sfi != methods.length) {
        System.arraycopy(staticFactories, 0, staticFactories = new MethodBinding[sfi], 0, sfi);
    }
    MethodBinding[] compatible = new MethodBinding[sfi];
    int compatibleIndex = 0;
    for (int i = 0; i < sfi; i++) {
        MethodBinding compatibleMethod = computeCompatibleMethod(staticFactories[i], argumentTypes,
                allocationSite);
        if (compatibleMethod != null) {
            if (compatibleMethod.isValidBinding())
                compatible[compatibleIndex++] = compatibleMethod;
        }
    }

    if (compatibleIndex == 0) {
        return null;
    }
    MethodBinding[] visible = new MethodBinding[compatibleIndex];
    int visibleIndex = 0;
    for (int i = 0; i < compatibleIndex; i++) {
        MethodBinding method = compatible[i];
        if (method.canBeSeenBy(allocationSite, this))
            visible[visibleIndex++] = method;
    }
    if (visibleIndex == 0) {
        return null;
    }
    return visibleIndex == 1 ? visible[0]
            : mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, allocationSite, allocationType);
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.ConstantPoolObjectMapper.java

License:Open Source License

/**
 * Map a type binding and convert it to a UTF8-Object.
 * @param typeBinding/* w  w w.  jav  a 2s .  c om*/
 * @param useGenerics should type parameters be respected (else use erasure)
 * @return ConstantPoolObject of type Utf8Tag
 */
public ConstantPoolObject mapTypeUtf8(TypeBinding typeBinding, boolean useGenerics) {
    //System.out.println("Sign of "+typeBinding+"="+new String(typeBinding.signature()));
    char[] prefix = null;
    if (typeBinding.isArrayType()) {
        // need to disassemble arrays, because we want to analyze the element type:
        ArrayBinding array = (ArrayBinding) typeBinding;
        prefix = new char[array.dimensions()];
        Arrays.fill(prefix, '[');
        typeBinding = array.leafComponentType;
    }
    if (typeBinding.isClass() || typeBinding.isInterface()) {
        ConstantPoolObject clazzCPO = new ConstantPoolObject(ClassTag,
                mapClass(this._srcMethod, typeBinding, getTeam(this._dstMethod)));
        typeBinding = clazzCPO.getClassObject();
    }
    char[] signature = useGenerics ? typeBinding.genericTypeSignature() : typeBinding.signature();

    if (prefix != null)
        signature = CharOperation.concat(prefix, signature);
    return new ConstantPoolObject(Utf8Tag, signature);
}