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

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

Introduction

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

Prototype

public boolean isTypeVariable() 

Source Link

Document

Returns true if the type was declared as a type variable

Usage

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

License:Open Source License

protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
    if (!matchesName(this.pattern.selector, method.selector))
        return IMPOSSIBLE_MATCH;

    int level = ACCURATE_MATCH;
    // look at return type only if declaring type is not specified
    if (this.pattern.declaringSimpleName == null) {
        // TODO (frederic) use this call to refine accuracy on return type
        // int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, this.pattern.returnTypeArguments, 0, method.returnType);
        int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification,
                method.returnType);//from w  ww .j av a2s.c o  m
        if (level > newLevel) {
            if (newLevel == IMPOSSIBLE_MATCH)
                return IMPOSSIBLE_MATCH;
            level = newLevel; // can only be downgraded
        }
    }

    // parameter types
    int parameterCount = this.pattern.parameterSimpleNames == null ? -1
            : this.pattern.parameterSimpleNames.length;
    if (parameterCount > -1) {
        // global verification
        if (method.parameters == null)
            return INACCURATE_MATCH;
        if (parameterCount != method.parameters.length)
            return IMPOSSIBLE_MATCH;
        if (!method.isValidBinding()
                && ((ProblemMethodBinding) method).problemId() == ProblemReasons.Ambiguous) {
            // return inaccurate match for ambiguous call (bug 80890)
            return INACCURATE_MATCH;
        }
        boolean foundTypeVariable = false;
        // verify each parameter
        for (int i = 0; i < parameterCount; i++) {
            TypeBinding argType = method.parameters[i];
            int newLevel = IMPOSSIBLE_MATCH;
            if (argType.isMemberType()) {
                // only compare source name for member type (bug 41018)
                newLevel = CharOperation.match(this.pattern.parameterSimpleNames[i], argType.sourceName(),
                        this.isCaseSensitive) ? ACCURATE_MATCH : IMPOSSIBLE_MATCH;
            } else {
                // TODO (frederic) use this call to refine accuracy on parameter types
                //             newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType);
                newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i],
                        this.pattern.parameterQualifications[i], argType);
            }
            if (level > newLevel) {
                if (newLevel == IMPOSSIBLE_MATCH) {
                    if (skipImpossibleArg) {
                        // Do not consider match as impossible while finding declarations and source level >= 1.5
                        // (see  bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763)
                        newLevel = level;
                    } else if (argType.isTypeVariable()) {
                        newLevel = level;
                        foundTypeVariable = true;
                    } else {
                        return IMPOSSIBLE_MATCH;
                    }
                }
                level = newLevel; // can only be downgraded
            }
        }
        if (foundTypeVariable) {
            if (!method.isStatic() && !method.isPrivate()) {
                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836, No point in textually comparing type variables, captures etc with concrete types.
                MethodBinding focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern);
                if (focusMethodBinding != null) {
                    if (matchOverriddenMethod(focusMethodBinding.declaringClass, focusMethodBinding, method)) {
                        return ACCURATE_MATCH;
                    }
                }
            }
            return IMPOSSIBLE_MATCH;
        }
    }

    return level;
}

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

License:Open Source License

/**
 * Returns whether the given type binding matches the given qualified pattern.
 * Returns ACCURATE_MATCH if it does.//from  w  ww . ja  v  a2  s  .c om
 * Returns INACCURATE_MATCH if resolve failed.
 * Returns IMPOSSIBLE_MATCH if it doesn't.
 */
protected int resolveLevelForType(char[] qualifiedPattern, TypeBinding type) {
    if (qualifiedPattern == null)
        return ACCURATE_MATCH;
    if (type == null || !type.isValidBinding())
        return INACCURATE_MATCH;

    // Type variable cannot be specified through pattern => this kind of binding cannot match it (see bug 79803)
    if (type.isTypeVariable())
        return IMPOSSIBLE_MATCH;

    // NOTE: if case insensitive search then qualifiedPattern is assumed to be lowercase

    char[] qualifiedPackageName = type.qualifiedPackageName();
    char[] qualifiedSourceName = qualifiedSourceName(type);
    char[] fullyQualifiedTypeName = qualifiedPackageName.length == 0 ? qualifiedSourceName
            : CharOperation.concat(qualifiedPackageName, qualifiedSourceName, '.');
    return CharOperation.match(qualifiedPattern, fullyQualifiedTypeName, this.isCaseSensitive) ? ACCURATE_MATCH
            : IMPOSSIBLE_MATCH;
}

From source file:com.redhat.ceylon.eclipse.core.model.mirror.UnknownTypeMirror.java

License:Open Source License

public JDTType(TypeBinding type, IdentityHashMap<TypeBinding, JDTType> originatingTypes) {
    originatingTypes.put(type, this);

    // type params are not qualified
    if (type instanceof TypeVariableBinding)
        qualifiedName = new String(type.qualifiedSourceName());
    else//  ww  w  . j  a  v a2s .c  om
        qualifiedName = JDTUtils.getFullyQualifiedName(type);

    typeKind = findKind(type);

    isPrimitive = type.isBaseType() && type.id != TypeIds.T_void && type.id != TypeIds.T_null;

    isRaw = type.isRawType();

    if (type instanceof ParameterizedTypeBinding && !(type instanceof RawTypeBinding)) {
        TypeBinding[] javaTypeArguments = ((ParameterizedTypeBinding) type).arguments;
        if (javaTypeArguments == null) {
            javaTypeArguments = new TypeBinding[0];
        }
        typeArguments = new ArrayList<TypeMirror>(javaTypeArguments.length);
        for (TypeBinding typeArgument : javaTypeArguments)
            typeArguments.add(toTypeMirror(typeArgument, type, this, originatingTypes));
    } else {
        typeArguments = Collections.emptyList();
    }

    if (type instanceof ArrayBinding) {
        TypeBinding jdtComponentType = ((ArrayBinding) type).elementsType();
        componentType = toTypeMirror(jdtComponentType, type, this, originatingTypes);
    } else {
        componentType = null;
    }

    if (type.isWildcard()) {
        WildcardBinding wildcardBinding = (WildcardBinding) type;
        if (wildcardBinding.boundKind == Wildcard.EXTENDS) {
            TypeBinding upperBoundBinding = wildcardBinding.bound;
            if (upperBoundBinding != null) {
                upperBound = toTypeMirror(upperBoundBinding, type, this, originatingTypes);
            }
        }
    } else if (type.isTypeVariable()) {
        TypeVariableBinding typeVariableBinding = (TypeVariableBinding) type;
        TypeBinding boundBinding = typeVariableBinding.firstBound; // TODO : we should confirm this
        if (boundBinding != null) {
            upperBound = toTypeMirror(boundBinding, type, this, originatingTypes);
        }
    } else {
        upperBound = null;
    }

    if (type.isWildcard()) {
        WildcardBinding wildcardBinding = (WildcardBinding) type;
        if (wildcardBinding.boundKind == Wildcard.SUPER) {
            TypeBinding lowerBoundBinding = wildcardBinding.bound;
            if (lowerBoundBinding != null) {
                lowerBound = toTypeMirror(lowerBoundBinding, type, this, originatingTypes);
            }
        }
    }

    if (type instanceof ParameterizedTypeBinding || type instanceof SourceTypeBinding
            || type instanceof BinaryTypeBinding) {
        ReferenceBinding refBinding = (ReferenceBinding) type;
        declaredClass = new JDTClass(refBinding, JDTModelLoader.toType(refBinding));
    }

    if (type instanceof TypeVariableBinding) {
        typeParameter = new JDTTypeParameter((TypeVariableBinding) type, this, originatingTypes);
    }
}

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

License:Open Source License

public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) {
    int dims = binding.dimensions();
    binding = binding.leafComponentType();

    // Primitives

    char[] base = null;

    switch (binding.id) {
    case TypeIds.T_int:
        base = TypeConstants.INT;//from  w  ww.  j a  va 2s  .c  om
        break;
    case TypeIds.T_long:
        base = TypeConstants.LONG;
        break;
    case TypeIds.T_short:
        base = TypeConstants.SHORT;
        break;
    case TypeIds.T_byte:
        base = TypeConstants.BYTE;
        break;
    case TypeIds.T_double:
        base = TypeConstants.DOUBLE;
        break;
    case TypeIds.T_float:
        base = TypeConstants.FLOAT;
        break;
    case TypeIds.T_boolean:
        base = TypeConstants.BOOLEAN;
        break;
    case TypeIds.T_char:
        base = TypeConstants.CHAR;
        break;
    case TypeIds.T_void:
        base = TypeConstants.VOID;
        break;
    case TypeIds.T_null:
        return null;
    }

    if (base != null) {
        if (dims > 0) {
            TypeReference result = new ArrayTypeReference(base, dims, pos(pos));
            setGeneratedBy(result, pos);
            return result;
        }
        TypeReference result = new SingleTypeReference(base, pos(pos));
        setGeneratedBy(result, pos);
        return result;
    }

    if (binding.isAnonymousType()) {
        ReferenceBinding ref = (ReferenceBinding) binding;
        ReferenceBinding[] supers = ref.superInterfaces();
        if (supers == null || supers.length == 0)
            supers = new ReferenceBinding[] { ref.superclass() };
        if (supers[0] == null) {
            TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3));
            setGeneratedBy(result, pos);
            return result;
        }
        return makeType(supers[0], pos, false);
    }

    if (binding instanceof CaptureBinding) {
        return makeType(((CaptureBinding) binding).wildcard, pos, allowCompound);
    }

    if (binding.isUnboundWildcard()) {
        if (!allowCompound) {
            TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3));
            setGeneratedBy(result, pos);
            return result;
        } else {
            Wildcard out = new Wildcard(Wildcard.UNBOUND);
            setGeneratedBy(out, pos);
            out.sourceStart = pos.sourceStart;
            out.sourceEnd = pos.sourceEnd;
            return out;
        }
    }

    if (binding.isWildcard()) {
        WildcardBinding wildcard = (WildcardBinding) binding;
        if (wildcard.boundKind == Wildcard.EXTENDS) {
            if (!allowCompound) {
                return makeType(wildcard.bound, pos, false);
            } else {
                Wildcard out = new Wildcard(Wildcard.EXTENDS);
                setGeneratedBy(out, pos);
                out.bound = makeType(wildcard.bound, pos, false);
                out.sourceStart = pos.sourceStart;
                out.sourceEnd = pos.sourceEnd;
                return out;
            }
        } else if (allowCompound && wildcard.boundKind == Wildcard.SUPER) {
            Wildcard out = new Wildcard(Wildcard.SUPER);
            setGeneratedBy(out, pos);
            out.bound = makeType(wildcard.bound, pos, false);
            out.sourceStart = pos.sourceStart;
            out.sourceEnd = pos.sourceEnd;
            return out;
        } else {
            TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3));
            setGeneratedBy(result, pos);
            return result;
        }
    }

    // Keep moving up via 'binding.enclosingType()' and gather generics from each binding. We stop after a local type, or a static type, or a top-level type.
    // Finally, add however many nullTypeArgument[] arrays as that are missing, inverse the list, toArray it, and use that as PTR's typeArgument argument.

    List<TypeReference[]> params = new ArrayList<TypeReference[]>();
    /* Calculate generics */ {
        TypeBinding b = binding;
        while (true) {
            boolean isFinalStop = b.isLocalType() || !b.isMemberType() || b.enclosingType() == null;

            TypeReference[] tyParams = null;
            if (b instanceof ParameterizedTypeBinding) {
                ParameterizedTypeBinding paramized = (ParameterizedTypeBinding) b;
                if (paramized.arguments != null) {
                    tyParams = new TypeReference[paramized.arguments.length];
                    for (int i = 0; i < tyParams.length; i++) {
                        tyParams[i] = makeType(paramized.arguments[i], pos, true);
                    }
                }
            }

            params.add(tyParams);
            if (isFinalStop)
                break;
            b = b.enclosingType();
        }
    }

    char[][] parts;

    if (binding.isTypeVariable()) {
        parts = new char[][] { binding.shortReadableName() };
    } else if (binding.isLocalType()) {
        parts = new char[][] { binding.sourceName() };
    } else {
        String[] pkg = new String(binding.qualifiedPackageName()).split("\\.");
        String[] name = new String(binding.qualifiedSourceName()).split("\\.");
        if (pkg.length == 1 && pkg[0].isEmpty())
            pkg = new String[0];
        parts = new char[pkg.length + name.length][];
        int ptr;
        for (ptr = 0; ptr < pkg.length; ptr++)
            parts[ptr] = pkg[ptr].toCharArray();
        for (; ptr < pkg.length + name.length; ptr++)
            parts[ptr] = name[ptr - pkg.length].toCharArray();
    }

    while (params.size() < parts.length)
        params.add(null);
    Collections.reverse(params);

    boolean isParamized = false;

    for (TypeReference[] tyParams : params) {
        if (tyParams != null) {
            isParamized = true;
            break;
        }
    }
    if (isParamized) {
        if (parts.length > 1) {
            TypeReference[][] typeArguments = params.toArray(new TypeReference[0][]);
            TypeReference result = new ParameterizedQualifiedTypeReference(parts, typeArguments, dims,
                    poss(pos, parts.length));
            setGeneratedBy(result, pos);
            return result;
        }
        TypeReference result = new ParameterizedSingleTypeReference(parts[0], params.get(0), dims, pos(pos));
        setGeneratedBy(result, pos);
        return result;
    }

    if (dims > 0) {
        if (parts.length > 1) {
            TypeReference result = new ArrayQualifiedTypeReference(parts, dims, poss(pos, parts.length));
            setGeneratedBy(result, pos);
            return result;
        }
        TypeReference result = new ArrayTypeReference(parts[0], dims, pos(pos));
        setGeneratedBy(result, pos);
        return result;
    }

    if (parts.length > 1) {
        TypeReference result = new QualifiedTypeReference(parts, poss(pos, parts.length));
        setGeneratedBy(result, pos);
        return result;
    }
    TypeReference result = new SingleTypeReference(parts[0], pos(pos));
    setGeneratedBy(result, pos);
    return result;
}

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

License:Open Source License

boolean isAcceptableReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
    // called when currentMethod's return type is compatible with inheritedMethod's return type

    if (inheritedMethod.declaringClass.isRawType())
        return true; // since the inheritedMethod comes from a raw type, the return type is always acceptable

    MethodBinding originalInherited = inheritedMethod.original();
    TypeBinding originalInheritedReturnType = originalInherited.returnType.leafComponentType();
    if (originalInheritedReturnType.isParameterizedTypeWithActualArguments())
        return !currentMethod.returnType.leafComponentType().isRawType(); // raw types issue a warning if inherited is parameterized

    TypeBinding currentReturnType = currentMethod.returnType.leafComponentType();
    switch (currentReturnType.kind()) {
    case Binding.TYPE_PARAMETER:
        if (currentReturnType == inheritedMethod.returnType.leafComponentType())
            return true;
        //$FALL-THROUGH$
    default:// ww w. ja va  2  s  .c  om
        if (originalInheritedReturnType.isTypeVariable())
            if (((TypeVariableBinding) originalInheritedReturnType).declaringElement == originalInherited)
                return false;
        return true;
    }
}

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 ww  w. j  a va 2 s .c  o 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.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java

License:Open Source License

/**
 * Check all parameters in methodSpec against the resolved role method.
 * Also record which parameters (including result) need translation (lifting/lowering).
 *
 * Pre: not called if parameter mappings are present.
 * @param methodSpec//from ww w  .j  a va2 s .co  m
 */
protected boolean internalCheckParametersCompatibility(MethodSpec methodSpec, TypeBinding[] roleParams,
        TypeBinding[] baseParams) {
    if (baseParams.length < roleParams.length) {
        this.scope.problemReporter().tooFewArgumentsInMethodMapping(this.roleMethodSpec, methodSpec,
                false/*callout*/);
        this.binding.tagBits |= TagBits.HasMappingIncompatibility;
        return false;
    } else {
        // before modifying the parameters array copy it:
        System.arraycopy(this.roleMethodSpec.parameters, 0,
                this.roleMethodSpec.parameters = new TypeBinding[roleParams.length], 0, roleParams.length);
        for (int j = 0; j < roleParams.length; j++) {
            TypeBinding baseParam = baseParams[j];
            TypeBinding roleParam = roleParams[j];
            if (baseParam.dimensions() != roleParam.dimensions()) {
                this.scope.problemReporter().incompatibleMappedArgument(baseParam, roleParam,
                        this.roleMethodSpec, j, /*callout*/false);
                this.binding.tagBits |= TagBits.HasMappingIncompatibility;
                continue; // no real type checking needed.
            }
            TypeBinding baseLeaf = baseParam.leafComponentType();
            TypeBinding roleLeaf = roleParam.leafComponentType();
            ASTNode location = (methodSpec.hasSignature) ? (ASTNode) methodSpec.arguments[j] : methodSpec;
            boolean compatibilityViaBaseAnchor = false;
            boolean hasReportedError = false;
            boolean isTypeVariable = false;
            try { // capture continue exits

                // unbound type variable matches everything:
                if (roleParam.isTypeVariable()) {
                    TypeVariableBinding typeVariableBinding = (TypeVariableBinding) roleParam;
                    if (typeVariableBinding.firstBound == null)
                        continue;
                    // use bound for type checking below, yet need not check two-way compatibility:
                    isTypeVariable = true;
                    roleLeaf = typeVariableBinding.firstBound.leafComponentType();
                }

                int dimensions = roleParam.dimensions();
                if (baseLeaf.isCompatibleWith(roleLeaf)) {
                    this.roleMethodSpec.parameters[j] = roleParam;
                    continue;
                }
                if (RoleTypeCreator.isCompatibleViaBaseAnchor(this.scope, baseLeaf, roleLeaf,
                        TokenNameBINDIN)) {
                    this.roleMethodSpec.parameters[j] = roleParam;
                    compatibilityViaBaseAnchor = true;
                    continue;
                }

                TypeBinding roleToLiftTo = null;
                if (isReplaceCallin()) {
                    TypeBinding roleSideType = roleLeaf;
                    if (roleSideType.isRole()) {
                        ReferenceBinding roleRef = (ReferenceBinding) roleSideType;
                        roleRef = (ReferenceBinding) TeamModel
                                .strengthenRoleType(this.scope.enclosingReceiverType(), roleRef);
                        if (TypeBinding.equalsEquals(roleRef.baseclass(), baseLeaf)) {
                            if (dimensions > 0) {
                                if (roleRef instanceof DependentTypeBinding)
                                    roleToLiftTo = ((DependentTypeBinding) roleRef).getArrayType(dimensions);
                                else
                                    roleToLiftTo = this.scope.createArrayType(roleRef, dimensions); // FIXME(SH): is this OK?
                            } else {
                                roleToLiftTo = roleRef;
                            }
                        }
                    }
                } else {
                    // this uses OTJLD 2.3.3(a) adaptation which is not reversible, ie., not usable for replace:
                    roleToLiftTo = TeamModel.getRoleToLiftTo(this.scope, baseParam, roleParam, false, location);
                }
                if (roleToLiftTo != null) {
                    // success by translation
                    methodSpec.argNeedsTranslation[j] = true;
                    this.roleMethodSpec.argNeedsTranslation[j] = true;
                    this.roleMethodSpec.parameters[j] = roleToLiftTo; // this applies to all bindings

                    // still need to check for ambiguity/abstract role:
                    ReferenceBinding enclosingTeam = this.scope.enclosingSourceType().enclosingType();
                    int iProblem = enclosingTeam.getTeamModel()
                            .canLiftingFail((ReferenceBinding) roleToLiftTo.leafComponentType());
                    if (iProblem > 0)
                        addRoleLiftingProblem((ReferenceBinding) roleToLiftTo.leafComponentType(), iProblem);

                    continue;
                }
                // check auto(un)boxing:
                if (this.scope.isBoxingCompatibleWith(baseLeaf, roleLeaf))
                    continue;

                if (roleParam instanceof ReferenceBinding) {
                    ReferenceBinding roleRef = (ReferenceBinding) roleParam;
                    if (roleRef.isRole() && roleRef.baseclass() != null) {
                        this.scope.problemReporter().typeMismatchErrorPotentialLift(location, baseParam,
                                roleParam, roleRef.baseclass());
                        hasReportedError = true;
                        continue;
                    }
                }
                // no compatibility detected:
                this.scope.problemReporter().incompatibleMappedArgument(baseParam, roleParam,
                        this.roleMethodSpec, j, /*callout*/false);
                hasReportedError = true;
            } finally {
                if (hasReportedError)
                    this.binding.tagBits |= TagBits.HasMappingIncompatibility;
                // regardless of continue, check this last because it is the least precise message:
                if (!hasReportedError && baseLeaf.isCompatibleWith(roleLeaf)) {
                    if (isReplaceCallin() && !isTypeVariable) {
                        boolean twowayCompatible = compatibilityViaBaseAnchor
                                ? RoleTypeCreator.isCompatibleViaBaseAnchor(this.scope, baseLeaf, roleLeaf,
                                        TokenNameBINDOUT)
                                : roleLeaf.isCompatibleWith(baseLeaf);
                        if (!twowayCompatible) {
                            // requires two-way compatibility (see additional paragraph in 4.5(d))
                            this.scope.problemReporter().typesNotTwowayCompatibleInReplace(baseParam, roleParam,
                                    location, j);
                        }
                    }
                }
            }
        }
    }
    return true; // unused in the callin case
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java

License:Open Source License

/** Check whether the baseSpec has a result compatible via replace. */
public void checkResultForReplace(MethodSpec baseSpec) {
    boolean typeIdentityRequired = true; // default unless return is type variable
    // covariant return requires a fresh type parameter for the role's return type:
    if (baseSpec.covariantReturn && this.roleMethodSpec.returnType != null) {
        TypeBinding resolvedRoleReturn = this.roleMethodSpec.returnType.resolvedType;
        if (resolvedRoleReturn != null) {
            if (!resolvedRoleReturn.isTypeVariable()) {
                this.scope.problemReporter()
                        .covariantReturnRequiresTypeParameter(this.roleMethodSpec.returnType);
                this.binding.tagBits |= TagBits.HasMappingIncompatibility;
            } else {
                // is the type parameter "fresh"?
                for (Argument arg : this.roleMethodSpec.arguments) {
                    if (typeUsesTypeVariable(arg.type.resolvedType.leafComponentType(), resolvedRoleReturn)) {
                        this.scope.problemReporter().duplicateUseOfTypeVariableInCallin(
                                this.roleMethodSpec.returnType, resolvedRoleReturn);
                        this.binding.tagBits |= TagBits.HasMappingIncompatibility;
                        break;
                    }//  w w  w.j  a  va2s . c  o  m
                }
            }
        }
    }
    TypeVariableBinding returnVariable = MethodModel
            .checkedGetReturnTypeVariable(this.roleMethodSpec.resolvedMethod);
    if (returnVariable != null) {
        // unbounded type variable always matches:
        if (returnVariable.firstBound == null)
            return;
        // in case of type variable only one-way compatibility is needed even for replace:
        typeIdentityRequired = false;
    }

    // now go for the actual type checking:
    TypeBinding baseReturn = baseSpec.resolvedMethod.returnType;
    TypeBinding roleReturn = MethodModel.getReturnType(this.roleMethodSpec.resolvedMethod);
    TypeBinding roleReturnLeaf = roleReturn != null ? roleReturn.leafComponentType() : null;
    if (roleReturnLeaf instanceof ReferenceBinding && ((ReferenceBinding) roleReturnLeaf).isRole()) {
        // strengthen:
        roleReturnLeaf = TeamModel.strengthenRoleType(this.scope.enclosingSourceType(), roleReturnLeaf);
        if (roleReturnLeaf == null) { // FIXME(SH): testcase and better handling
            String roleReturnName = roleReturn != null ? new String(roleReturn.readableName())
                    : "null return type"; //$NON-NLS-1$
            throw new InternalCompilerError("role strengthening for " + roleReturnName + " -> null"); //$NON-NLS-1$ //$NON-NLS-2$
        }

        // bound roles use their topmost bound super:
        if (((ReferenceBinding) roleReturnLeaf).baseclass() != null)
            roleReturnLeaf = RoleModel.getTopmostBoundRole(this.scope, (ReferenceBinding) roleReturnLeaf);

        // need the RTB:
        if (!(roleReturnLeaf instanceof DependentTypeBinding))
            roleReturnLeaf = RoleTypeCreator.maybeWrapUnqualifiedRoleType(roleReturnLeaf,
                    this.scope.enclosingSourceType());

        // array?
        int dims = roleReturn != null ? roleReturn.dimensions() : 0;
        if (dims == 0) {
            roleReturn = roleReturnLeaf;
            this.realRoleReturn = roleReturnLeaf;
        } else {
            roleReturn = ((DependentTypeBinding) roleReturnLeaf).getArrayType(dims);
            this.realRoleReturn = ((DependentTypeBinding) roleReturnLeaf).getArrayType(dims);
        }
    }
    if (baseReturn == null || baseReturn == TypeBinding.VOID) {
        // OTJLD 4.4(b): "A callin method bound with replace
        //                to a base method returning void
        //                must not declare a non-void result."
        if (!(roleReturn == null || roleReturn == TypeBinding.VOID)) {
            this.scope.problemReporter().callinIllegalRoleReturnReturn(baseSpec, this.roleMethodSpec);
            this.binding.tagBits |= TagBits.HasMappingIncompatibility;
        }
    } else {
        if (roleReturn == null || roleReturn == TypeBinding.VOID) {
            this.baseMethodNeedingResultFromBasecall = baseSpec;
            // will be reported in checkBaseResult().
            return;
        }

        TypeBinding baseLeaf = baseReturn.leafComponentType();
        if (baseLeaf instanceof DependentTypeBinding) {
            // instantiate relative to Role._OT$base:
            ReferenceBinding enclosingRole = this.scope.enclosingSourceType();
            FieldBinding baseField = enclosingRole.getField(IOTConstants._OT_BASE, true);
            if (baseField != null && baseField.isValidBinding())
                baseReturn = baseField.getRoleTypeBinding((ReferenceBinding) baseLeaf, baseReturn.dimensions());
        }

        // check auto(un)boxing:
        if (this.scope.isBoxingCompatibleWith(roleReturn, baseReturn))
            return;

        Config oldConfig = Config.createOrResetConfig(this);
        try {
            if (!roleReturn.isCompatibleWith(baseReturn)) {
                if (typeIdentityRequired) {
                    this.scope.problemReporter().callinIncompatibleReturnType(baseSpec, this.roleMethodSpec);
                    this.binding.tagBits |= TagBits.HasMappingIncompatibility;
                    return;
                }
                // else we still needed the lowering test
            }
            // callin replace requires two way compatibility:
            baseSpec.returnNeedsTranslation = Config.getLoweringRequired();

        } finally {
            Config.removeOrRestore(oldConfig, this);
        }
        // from now on don't bother with arrays any more (dimensions have been checked):
        roleReturn = roleReturn.leafComponentType();
        baseReturn = baseReturn.leafComponentType();
        TypeBinding translatedReturn = baseSpec.returnNeedsTranslation
                ? ((ReferenceBinding) roleReturn).baseclass()
                : roleReturn;
        if (translatedReturn.isTypeVariable()) {
            TypeBinding firstBound = ((TypeVariableBinding) translatedReturn).firstBound;
            if (firstBound != null)
                translatedReturn = firstBound;
        }
        if (!baseReturn.isCompatibleWith(translatedReturn)) {
            this.scope.problemReporter().callinIncompatibleReturnTypeBaseCall(baseSpec, this.roleMethodSpec);
            this.binding.tagBits |= TagBits.HasMappingIncompatibility;
        }
    }
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java

License:Open Source License

private boolean typeUsesTypeVariable(TypeBinding type, TypeBinding variable) {
    if (TypeBinding.equalsEquals(type.leafComponentType(), variable))
        return true;
    for (TypeVariableBinding t : type.typeVariables())
        if (typeUsesTypeVariable(t, variable))
            return true;
    if (type.isTypeVariable()) {
        if (typeUsesTypeVariable(((ReferenceBinding) type).superclass(), variable))
            return true;
        for (TypeBinding superIfc : ((ReferenceBinding) type).superInterfaces())
            if (typeUsesTypeVariable(superIfc, variable))
                return true;
    }/* w w w .ja v a2  s  .  co m*/
    return false;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference.java

License:Open Source License

@Override
public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
    TypeBinding baseType = this.resolvedType = this.baseReference.resolveType(scope);
    if (this.roleReference.getTypeName().length > 1) {
        scope.problemReporter().qualifiedLiftingType(this.roleReference, scope.enclosingSourceType());
        return invalidate(baseType);
    }/*  w w w.j  a va 2 s.c om*/
    TypeBinding roleType = this.roleReference.resolveType(scope);
    if (scope.kind != Scope.BLOCK_SCOPE) { // not a catch block?
        if (!TeamModel.isAnyTeam(scope.enclosingSourceType())) {
            scope.problemReporter().liftingTypeNotAllowedHere(scope.methodScope().referenceContext, this);
            return invalidate(roleType);
        }
    }
    if (baseType == null || baseType instanceof MissingTypeBinding)
        return invalidate(roleType);
    if (roleType == null || roleType instanceof MissingTypeBinding)
        return invalidate(baseType);
    if (roleType.isArrayType()) {
        baseType = baseType.leafComponentType();
        roleType = roleType.leafComponentType();
    }
    if (roleType.isBaseType()) {
        scope.problemReporter().primitiveTypeNotAllowedForLifting(scope.referenceType(), this.roleReference,
                roleType);
        return invalidate(roleType);
    }
    if (baseType.isBaseType()) {
        scope.problemReporter().primitiveTypeNotAllowedForLifting(scope.referenceType(), this.baseReference,
                baseType);
        return invalidate(roleType);
    }

    ReferenceBinding roleRefType = (ReferenceBinding) roleType;
    if (!roleRefType.isValidBinding()) // already reported.
        return invalidate(roleType);

    if (!roleRefType.isDirectRole()) {
        scope.problemReporter().needRoleInLiftingType(scope.referenceType(), this.roleReference, roleType);
        return invalidate(roleType);
    }
    if (roleRefType.isSynthInterface())
        roleRefType = roleRefType.getRealClass();

    if (roleRefType.roleModel.hasBaseclassProblem()) {// already reported for the role class.
        scope.referenceContext().tagAsHavingErrors(); // -> mark method as erroneous, too.
        return invalidate(roleType);
    }

    // TODO (SH): maybe look for bound sub-type?
    // Note (SH): calling baseclass() requires STATE_LENV_DONE_FIELDS_AND_METHODS:
    Dependencies.ensureBindingState(roleRefType, ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS);

    if (baseType.isTypeVariable() && ((TypeVariableBinding) baseType).roletype != null) {
        // resolving "<B base R> as R":
        roleRefType = ((TypeVariableBinding) baseType).roletype;
        // ambiguity is handled by _OT$lift_dynamic which may or may not declare LiftingFailedException
    } else if ((baseType.tagBits & TagBits.HierarchyHasProblems) != 0) {
        // already reported (?)
    } else {
        // static adjustment (OTJLD 2.3.2(a)):
        roleRefType = (ReferenceBinding) TeamModel.getRoleToLiftTo(scope, baseType, roleRefType, true, this);
        if (roleRefType == null)
            roleRefType = (ReferenceBinding) roleType; // revert unsuccessful adjustment
        if (roleRefType.baseclass() == null
                || RoleModel.hasTagBit(roleRefType, RoleModel.BaseclassHasProblems)) {
            scope.problemReporter().roleNotBoundCantLift(scope.referenceType(), this.roleReference, roleType);
            return invalidate(roleType);
        }
        if (baseType.isRole()) // see http://trac.objectteams.org/ot/ticket/73
            baseType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(baseType, scope.enclosingReceiverType());
        if (baseType == null)
            return invalidate(roleType);
        Config oldConfig = Config.createOrResetConfig(this);
        try {
            // fetch role's base class and perform substitutions:
            ReferenceBinding roleBase = roleRefType.baseclass();
            if (roleType.isParameterizedType()) {
                ParameterizedTypeBinding parameterizedRole = (ParameterizedTypeBinding) roleType;
                TypeBinding[] typeArgs = parameterizedRole.arguments;
                ITeamAnchor anchor = null;
                if (roleRefType.baseclass() instanceof RoleTypeBinding)
                    anchor = ((RoleTypeBinding) roleRefType.baseclass())._teamAnchor;
                roleBase = parameterizedRole.environment.createParameterizedType(
                        (ReferenceBinding) roleBase.original(), typeArgs, anchor, -1, roleBase.enclosingType(),
                        roleBase.getTypeAnnotations());
            }
            // THE compatibility check:
            if (!baseType.isCompatibleWith(roleBase) || Config.getLoweringRequired()) {
                scope.problemReporter().incompatibleBaseForRole(scope.referenceType(), this, roleType,
                        baseType);
                return invalidate(roleType);
            }
        } finally {
            Config.removeOrRestore(oldConfig, this);
        }
    }
    return this.resolvedType;
}