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

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

Introduction

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

Prototype

public boolean isCompatibleWith(TypeBinding right) 

Source Link

Usage

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

License:Open Source License

protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments,
        boolean hasTypeParameters) {
    // Only possible if locator has an unit scope.
    if (locator.unitScope == null)
        return;//from w w  w . ja v  a2 s.co  m

    // First compare lengthes
    int patternTypeArgsLength = patternArguments == null ? 0 : patternArguments.length;
    int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length;

    // Initialize match rule
    int matchRule = this.match.getRule();
    if (this.match.isRaw()) {
        if (patternTypeArgsLength != 0) {
            matchRule &= ~SearchPattern.R_FULL_MATCH;
        }
    }
    if (hasTypeParameters) {
        matchRule = SearchPattern.R_ERASURE_MATCH;
    }

    // Compare arguments lengthes
    if (patternTypeArgsLength == typeArgumentsLength) {
        if (!this.match.isRaw() && hasTypeParameters) {
            // generic patterns are always not compatible match
            this.match.setRule(SearchPattern.R_ERASURE_MATCH);
            return;
        }
    } else {
        if (patternTypeArgsLength == 0) {
            if (!this.match.isRaw() || hasTypeParameters) {
                this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
            }
        } else if (typeArgumentsLength == 0) {
            // raw binding is always compatible
            this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
        } else {
            this.match.setRule(0); // impossible match
        }
        return;
    }
    if (argumentsBinding == null || patternArguments == null) {
        this.match.setRule(matchRule);
        return;
    }

    // Compare binding for each type argument only if pattern is not erasure only and at first level
    if (!hasTypeParameters && !this.match.isRaw() && (this.match.isEquivalent() || this.match.isExact())) {
        for (int i = 0; i < typeArgumentsLength; i++) {
            // Get parameterized type argument binding
            TypeBinding argumentBinding = argumentsBinding[i];
            if (argumentBinding instanceof CaptureBinding) {
                WildcardBinding capturedWildcard = ((CaptureBinding) argumentBinding).wildcard;
                if (capturedWildcard != null)
                    argumentBinding = capturedWildcard;
            }
            // Get binding for pattern argument
            char[] patternTypeArgument = patternArguments[i];
            char patternWildcard = patternTypeArgument[0];
            char[] patternTypeName = patternTypeArgument;
            int patternWildcardKind = -1;
            switch (patternWildcard) {
            case Signature.C_STAR:
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    if (wildcardBinding.boundKind == Wildcard.UNBOUND)
                        continue;
                }
                matchRule &= ~SearchPattern.R_FULL_MATCH;
                continue; // unbound parameter always match
            case Signature.C_EXTENDS:
                patternWildcardKind = Wildcard.EXTENDS;
                patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
                break;
            case Signature.C_SUPER:
                patternWildcardKind = Wildcard.SUPER;
                patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
                break;
            default:
                break;
            }
            patternTypeName = Signature.toCharArray(patternTypeName);
            TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName);

            // If have no binding for pattern arg, then we won't be able to refine accuracy
            if (patternBinding == null) {
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    if (wildcardBinding.boundKind == Wildcard.UNBOUND) {
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                    } else {
                        this.match.setRule(SearchPattern.R_ERASURE_MATCH);
                        return;
                    }
                }
                continue;
            }

            // Verify tha pattern binding is compatible with match type argument binding
            switch (patternWildcard) {
            case Signature.C_STAR: // UNBOUND pattern
                // unbound always match => skip to next argument
                matchRule &= ~SearchPattern.R_FULL_MATCH;
                continue;
            case Signature.C_EXTENDS: // EXTENDS pattern
                if (argumentBinding.isWildcard()) { // argument is a wildcard
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    // It's ok if wildcards are identical
                    if (wildcardBinding.boundKind == patternWildcardKind
                            && wildcardBinding.bound == patternBinding) {
                        continue;
                    }
                    // Look for wildcard compatibility
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        if (wildcardBinding.bound == null
                                || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
                            // valid when arg extends a subclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.SUPER:
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (argumentBinding.isCompatibleWith(patternBinding)) {
                    // valid when arg is a subclass of pattern
                    matchRule &= ~SearchPattern.R_FULL_MATCH;
                    continue;
                }
                break;
            case Signature.C_SUPER: // SUPER pattern
                if (argumentBinding.isWildcard()) { // argument is a wildcard
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    // It's ok if wildcards are identical
                    if (wildcardBinding.boundKind == patternWildcardKind
                            && wildcardBinding.bound == patternBinding) {
                        continue;
                    }
                    // Look for wildcard compatibility
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        break;
                    case Wildcard.SUPER:
                        if (wildcardBinding.bound == null
                                || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
                            // valid only when arg super a superclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (patternBinding.isCompatibleWith(argumentBinding)) {
                    // valid only when arg is a superclass of pattern
                    matchRule &= ~SearchPattern.R_FULL_MATCH;
                    continue;
                }
                break;
            default:
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        if (wildcardBinding.bound == null
                                || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
                            // valid only when arg extends a superclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.SUPER:
                        if (wildcardBinding.bound == null
                                || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
                            // valid only when arg super a subclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (argumentBinding == patternBinding)
                    // valid only when arg is equals to pattern
                    continue;
                break;
            }

            // Argument does not match => erasure match will be the only possible one
            this.match.setRule(SearchPattern.R_ERASURE_MATCH);
            return;
        }
    }

    // Set match rule
    this.match.setRule(matchRule);
}

From source file:lombok.eclipse.agent.PatchExtensionMethod.java

License:Open Source License

private static List<MethodBinding> getApplicableExtensionMethodsDefinedInProvider(EclipseNode typeNode,
        ReferenceBinding extensionMethodProviderBinding, TypeBinding receiverType) {

    List<MethodBinding> extensionMethods = new ArrayList<MethodBinding>();
    CompilationUnitScope cuScope = ((CompilationUnitDeclaration) typeNode.top().get()).scope;
    for (MethodBinding method : extensionMethodProviderBinding.methods()) {
        if (!method.isStatic())
            continue;
        if (!method.isPublic())
            continue;
        if (method.parameters == null || method.parameters.length == 0)
            continue;
        TypeBinding firstArgType = method.parameters[0];
        if (receiverType.isProvablyDistinct(firstArgType)
                && !receiverType.isCompatibleWith(firstArgType.erasure()))
            continue;
        TypeBinding[] argumentTypes = Arrays.copyOfRange(method.parameters, 1, method.parameters.length);
        if ((receiverType instanceof ReferenceBinding) && ((ReferenceBinding) receiverType)
                .getExactMethod(method.selector, argumentTypes, cuScope) != null)
            continue;
        extensionMethods.add(method);/*from   ww w  .  j  av a2 s.co  m*/
    }
    return extensionMethods;
}

From source file:org.eclipse.che.jdt.internal.core.search.matching.PatternLocator.java

License:Open Source License

protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments,
        boolean hasTypeParameters) {
    // Only possible if locator has an unit scope.
    if (locator.unitScope == null)
        return;/*  w  w  w.  j  a  v a  2  s .  c  o m*/

    // First compare lengthes
    int patternTypeArgsLength = patternArguments == null ? 0 : patternArguments.length;
    int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length;

    // Initialize match rule
    int matchRule = this.match.getRule();
    if (this.match.isRaw()) {
        if (patternTypeArgsLength != 0) {
            matchRule &= ~SearchPattern.R_FULL_MATCH;
        }
    }
    if (hasTypeParameters) {
        matchRule = SearchPattern.R_ERASURE_MATCH;
    }

    // Compare arguments lengthes
    if (patternTypeArgsLength == typeArgumentsLength) {
        if (!this.match.isRaw() && hasTypeParameters) {
            // generic patterns are always not compatible match
            this.match.setRule(SearchPattern.R_ERASURE_MATCH);
            return;
        }
    } else {
        if (patternTypeArgsLength == 0) {
            if (!this.match.isRaw() || hasTypeParameters) {
                this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
            }
        } else if (typeArgumentsLength == 0) {
            // raw binding is always compatible
            this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
        } else {
            this.match.setRule(0); // impossible match
        }
        return;
    }
    if (argumentsBinding == null || patternArguments == null) {
        this.match.setRule(matchRule);
        return;
    }

    // Compare binding for each type argument only if pattern is not erasure only and at first level
    if (!hasTypeParameters && !this.match.isRaw() && (this.match.isEquivalent() || this.match.isExact())) {
        for (int i = 0; i < typeArgumentsLength; i++) {
            // Get parameterized type argument binding
            TypeBinding argumentBinding = argumentsBinding[i];
            if (argumentBinding instanceof CaptureBinding) {
                WildcardBinding capturedWildcard = ((CaptureBinding) argumentBinding).wildcard;
                if (capturedWildcard != null)
                    argumentBinding = capturedWildcard;
            }
            // Get binding for pattern argument
            char[] patternTypeArgument = patternArguments[i];
            char patternWildcard = patternTypeArgument[0];
            char[] patternTypeName = patternTypeArgument;
            int patternWildcardKind = -1;
            switch (patternWildcard) {
            case Signature.C_STAR:
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    if (wildcardBinding.boundKind == Wildcard.UNBOUND)
                        continue;
                }
                matchRule &= ~SearchPattern.R_FULL_MATCH;
                continue; // unbound parameter always match
            case Signature.C_EXTENDS:
                patternWildcardKind = Wildcard.EXTENDS;
                patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
                break;
            case Signature.C_SUPER:
                patternWildcardKind = Wildcard.SUPER;
                patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
                break;
            default:
                break;
            }
            patternTypeName = Signature.toCharArray(patternTypeName);
            TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName);

            // If have no binding for pattern arg, then we won't be able to refine accuracy
            if (patternBinding == null) {
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    if (wildcardBinding.boundKind == Wildcard.UNBOUND) {
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                    } else {
                        this.match.setRule(SearchPattern.R_ERASURE_MATCH);
                        return;
                    }
                }
                continue;
            }

            // Verify the pattern binding is compatible with match type argument binding
            switch (patternWildcard) {
            case Signature.C_STAR: // UNBOUND pattern
                // unbound always match => skip to next argument
                matchRule &= ~SearchPattern.R_FULL_MATCH;
                continue;
            case Signature.C_EXTENDS: // EXTENDS pattern
                if (argumentBinding.isWildcard()) { // argument is a wildcard
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    // It's ok if wildcards are identical
                    if (wildcardBinding.boundKind == patternWildcardKind
                            && TypeBinding.equalsEquals(wildcardBinding.bound, patternBinding)) {
                        continue;
                    }
                    // Look for wildcard compatibility
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        if (wildcardBinding.bound == null
                                || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
                            // valid when arg extends a subclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.SUPER:
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (argumentBinding.isCompatibleWith(patternBinding)) {
                    // valid when arg is a subclass of pattern
                    matchRule &= ~SearchPattern.R_FULL_MATCH;
                    continue;
                }
                break;
            case Signature.C_SUPER: // SUPER pattern
                if (argumentBinding.isWildcard()) { // argument is a wildcard
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    // It's ok if wildcards are identical
                    if (wildcardBinding.boundKind == patternWildcardKind
                            && TypeBinding.equalsEquals(wildcardBinding.bound, patternBinding)) {
                        continue;
                    }
                    // Look for wildcard compatibility
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        break;
                    case Wildcard.SUPER:
                        if (wildcardBinding.bound == null
                                || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
                            // valid only when arg super a superclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (patternBinding.isCompatibleWith(argumentBinding)) {
                    // valid only when arg is a superclass of pattern
                    matchRule &= ~SearchPattern.R_FULL_MATCH;
                    continue;
                }
                break;
            default:
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        if (wildcardBinding.bound == null
                                || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
                            // valid only when arg extends a superclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.SUPER:
                        if (wildcardBinding.bound == null
                                || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
                            // valid only when arg super a subclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (TypeBinding.equalsEquals(argumentBinding, patternBinding))
                    // valid only when arg is equals to pattern
                    continue;
                break;
            }

            // Argument does not match => erasure match will be the only possible one
            this.match.setRule(SearchPattern.R_ERASURE_MATCH);
            return;
        }
    }

    // Set match rule
    this.match.setRule(matchRule);
}

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

License:Open Source License

public static int compareTypes(TypeBinding left, TypeBinding right) {
    if (left.isCompatibleWith(right))
        return Scope.EQUAL_OR_MORE_SPECIFIC;
    if (right.isCompatibleWith(left))
        return Scope.MORE_GENERIC;
    return Scope.NOT_RELATED;
}

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

License:Open Source License

public static TypeBinding[] greaterLowerBound(TypeBinding[] types) {
    if (types == null)
        return null;
    int length = types.length;
    if (length == 0)
        return null;
    TypeBinding[] result = types;//  w  w  w.  j  a  v a  2 s  .c  om
    int removed = 0;
    for (int i = 0; i < length; i++) {
        TypeBinding iType = result[i];
        if (iType == null)
            continue;
        for (int j = 0; j < length; j++) {
            if (i == j)
                continue;
            TypeBinding jType = result[j];
            if (jType == null)
                continue;
            if (iType.isCompatibleWith(jType)) { // if Vi <: Vj, Vj is removed
                if (result == types) { // defensive copy
                    System.arraycopy(result, 0, result = new TypeBinding[length], 0, length);
                }
                result[j] = null;
                removed++;
            }
        }
    }
    if (removed == 0)
        return result;
    if (length == removed)
        return null; // how is this possible ???
    TypeBinding[] trimmedResult = new TypeBinding[length - removed];
    for (int i = 0, index = 0; i < length; i++) {
        TypeBinding iType = result[i];
        if (iType != null) {
            trimmedResult[index++] = iType;
        }
    }
    return trimmedResult;
}

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

License:Open Source License

protected boolean isAcceptableMethod(MethodBinding one, MethodBinding two) {
    TypeBinding[] oneParams = one.parameters;
    TypeBinding[] twoParams = two.parameters;
    int oneParamsLength = oneParams.length;
    int twoParamsLength = twoParams.length;
    if (oneParamsLength == twoParamsLength) {
        /* Below 1.5, discard any generics we have left in for the method verifier's benefit, (so it
           can detect method overriding properly in the presence of generic super types.) This is so
           as to allow us to determine whether we have been handed an acceptable method in 1.4 terms
           without all the 1.5isms below kicking in and spoiling the party.
           See https://bugs.eclipse.org/bugs/show_bug.cgi?id=331446
        *///from   w ww  .  j ava  2 s . c  o m
        boolean applyErasure = environment().globalOptions.sourceLevel < ClassFileConstants.JDK1_5;
        next: for (int i = 0; i < oneParamsLength; i++) {
            TypeBinding oneParam = applyErasure ? oneParams[i].erasure() : oneParams[i];
            TypeBinding twoParam = applyErasure ? twoParams[i].erasure() : twoParams[i];
            if (oneParam == twoParam || oneParam.isCompatibleWith(twoParam)) {
                if (two.declaringClass.isRawType())
                    continue next;

                TypeBinding leafComponentType = two.original().parameters[i].leafComponentType();
                TypeBinding originalTwoParam = applyErasure ? leafComponentType.erasure() : leafComponentType;
                switch (originalTwoParam.kind()) {
                case Binding.TYPE_PARAMETER:
                    if (((TypeVariableBinding) originalTwoParam).hasOnlyRawBounds())
                        continue next;
                    //$FALL-THROUGH$
                case Binding.WILDCARD_TYPE:
                case Binding.INTERSECTION_TYPE:
                case Binding.PARAMETERIZED_TYPE:
                    TypeBinding originalOneParam = one.original().parameters[i].leafComponentType();
                    switch (originalOneParam.kind()) {
                    case Binding.TYPE:
                    case Binding.GENERIC_TYPE:
                        TypeBinding inheritedTwoParam = oneParam.findSuperTypeOriginatingFrom(twoParam);
                        if (inheritedTwoParam == null || !inheritedTwoParam.leafComponentType().isRawType())
                            break;
                        return false;
                    case Binding.TYPE_PARAMETER:
                        if (!((TypeVariableBinding) originalOneParam).upperBound().isRawType())
                            break;
                        return false;
                    case Binding.RAW_TYPE:
                        // originalOneParam is RAW so it cannot be more specific than a wildcard or parameterized type
                        return false;
                    }
                }
            } else {
                if (i == oneParamsLength - 1 && one.isVarargs() && two.isVarargs()) {
                    TypeBinding eType = ((ArrayBinding) twoParam).elementsType();
                    if (oneParam == eType || oneParam.isCompatibleWith(eType))
                        return true; // special case to choose between 2 varargs methods when the last arg is Object[]
                }
                return false;
            }
        }
        return true;
    }

    if (one.isVarargs() && two.isVarargs()) {
        if (oneParamsLength > twoParamsLength) {
            // special case when autoboxing makes (int, int...) better than (Object...) but not (int...) or (Integer, int...)
            if (((ArrayBinding) twoParams[twoParamsLength - 1]).elementsType().id != TypeIds.T_JavaLangObject)
                return false;
        }
        // check that each parameter before the vararg parameters are compatible (no autoboxing allowed here)
        for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--)
            if (oneParams[i] != twoParams[i] && !oneParams[i].isCompatibleWith(twoParams[i]))
                return false;
        if (parameterCompatibilityLevel(one, twoParams) == NOT_COMPATIBLE
                && parameterCompatibilityLevel(two, oneParams) == VARARGS_COMPATIBLE)
            return true;
    }
    return false;
}

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

License:Open Source License

public boolean isBoxingCompatibleWith(TypeBinding expressionType, TypeBinding targetType) {
    LookupEnvironment environment = environment();
    if (environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5
            || expressionType.isBaseType() == targetType.isBaseType())
        return false;

    // check if autoboxed type is compatible
    TypeBinding convertedType = environment.computeBoxingType(expressionType);
    return convertedType == targetType || convertedType.isCompatibleWith(targetType);
}

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

License:Open Source License

public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments) {
    TypeBinding[] parameters = method.parameters;
    int paramLength = parameters.length;
    int argLength = arguments.length;

    if (compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
        if (paramLength != argLength)
            return NOT_COMPATIBLE;
        for (int i = 0; i < argLength; i++) {
            TypeBinding param = parameters[i];
            TypeBinding arg = arguments[i];
            //https://bugs.eclipse.org/bugs/show_bug.cgi?id=330445
            if (arg != param && !arg.isCompatibleWith(param.erasure()))
                return NOT_COMPATIBLE;
        }/*from  ww w.j a  va2 s.c  om*/
        return COMPATIBLE;
    }

    int level = COMPATIBLE; // no autoboxing or varargs support needed
    int lastIndex = argLength;
    LookupEnvironment env = environment();
    if (method.isVarargs()) {
        lastIndex = paramLength - 1;
        if (paramLength == argLength) { // accept X or X[] but not X[][]
            TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition
            TypeBinding arg = arguments[lastIndex];
            if (param != arg) {
                level = parameterCompatibilityLevel(arg, param, env);
                if (level == NOT_COMPATIBLE) {
                    // expect X[], is it called with X
                    param = ((ArrayBinding) param).elementsType();
                    if (parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE)
                        return NOT_COMPATIBLE;
                    level = VARARGS_COMPATIBLE; // varargs support needed
                }
            }
        } else {
            if (paramLength < argLength) { // all remaining argument types must be compatible with the elementsType of varArgType
                TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType();
                for (int i = lastIndex; i < argLength; i++) {
                    TypeBinding arg = arguments[i];
                    if (param != arg && parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE)
                        return NOT_COMPATIBLE;
                }
            } else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
                return NOT_COMPATIBLE;
            }
            level = VARARGS_COMPATIBLE; // varargs support needed
        }
    } else if (paramLength != argLength) {
        return NOT_COMPATIBLE;
    }
    // now compare standard arguments from 0 to lastIndex
    for (int i = 0; i < lastIndex; i++) {
        TypeBinding param = parameters[i];
        TypeBinding arg = arguments[i];
        if (arg != param) {
            int newLevel = parameterCompatibilityLevel(arg, param, env);
            if (newLevel == NOT_COMPATIBLE)
                return NOT_COMPATIBLE;
            if (newLevel > level)
                level = newLevel;
        }
    }
    return level;
}

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

License:Open Source License

private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env) {
    // only called if env.options.sourceLevel >= ClassFileConstants.JDK1_5
    if (arg.isCompatibleWith(param))
        return COMPATIBLE;
    if (arg.isBaseType() != param.isBaseType()) {
        TypeBinding convertedType = env.computeBoxingType(arg);
        if (convertedType == param || convertedType.isCompatibleWith(param))
            return AUTOBOX_COMPATIBLE;
    }/*www . j ava  2s .  co m*/
    return NOT_COMPATIBLE;
}

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

License:Open Source License

private void resolveSyntheticBaseCallSurrogate(MethodDeclaration outerCallinMethod, BlockScope scope,
        WeavingScheme weavingScheme) {/* w ww . ja v  a2 s .c  om*/
    // find the method:
    AbstractMethodDeclaration callinMethodDecl = outerCallinMethod;
    if (callinMethodDecl == null) {
        if (checkContext(scope)) {
            callinMethodDecl = scope.methodScope().referenceMethod();
        } else {
            return; // error reported by checkContext
        }
    }
    MethodBinding callinMethod = callinMethodDecl.binding;
    if (callinMethod == null) {
        if (callinMethodDecl.ignoreFurtherInvestigation)
            return;
        throw new InternalCompilerError("Unresolved method without an error"); //$NON-NLS-1$
    }
    // check name match:
    if (!CharOperation.equals(this._sendOrig.selector, callinMethod.selector))
        scope.problemReporter().baseCallNotSameMethod(callinMethodDecl, this._sendOrig);

    // find the receiver type:
    this._receiver.resolve(scope);
    int depth = 0;
    while (this._receiver.resolvedType.isLocalType()) {
        this._receiver.resolvedType = this._receiver.resolvedType.enclosingType();
        depth++;
    }
    this._receiver.bits |= depth << DepthSHIFT;
    if (this._receiver.resolvedType instanceof ReferenceBinding) {
        ReferenceBinding receiverType = (ReferenceBinding) this._receiver.resolvedType;
        this._receiver.resolvedType = receiverType.getRealClass();
    }

    // resolve arguments:
    TypeBinding[] sendparams = new TypeBinding[this._sendOrig.arguments.length];
    for (int i = 0; i < sendparams.length; i++)
        sendparams[i] = this._sendOrig.arguments[i].resolveType(scope);

    // check arguments:
    int sourceArgsLen = 0;
    if (this.sourceArgs != null)
        sourceArgsLen = this.sourceArgs.length;
    TypeBinding[] methodParams = callinMethod.getSourceParameters();
    if (sourceArgsLen != methodParams.length) {
        scope.problemReporter().baseCallDoesntMatchRoleMethodSignature(this);
    } else {
        for (int i = 0; i < sourceArgsLen; i++) {
            TypeBinding srcArgType = this.sourceArgs[i].resolvedType;
            if (srcArgType == null) {
                if (!callinMethodDecl.hasErrors())
                    throw new InternalCompilerError(
                            "Unexpected: srcArgType should only ever be missing in declarations with reported errors"); //$NON-NLS-1$
                continue;
            }
            if (!srcArgType.isCompatibleWith(methodParams[i])) {
                if (isBoxingCompatible(srcArgType, methodParams[i], this.sourceArgs[i], scope)) {
                    int enhancedArgIdx = i + MethodSignatureEnhancer.getEnhancingArgLen(weavingScheme) + 1; // normal enhancement plus isSuperAccess flag
                    this._sendOrig.arguments[enhancedArgIdx].computeConversion(scope, methodParams[i],
                            srcArgType);
                } else {
                    scope.problemReporter().baseCallDoesntMatchRoleMethodSignature(this);
                    break;
                }
            }
        }
    }

    // create and link the synthetic method binding:
    MethodBinding surrogate = null;
    MethodModel model = callinMethod.model;
    if (model != null)
        surrogate = model.getBaseCallSurrogate();
    if (surrogate == null) {
        SourceTypeBinding receiverClass = ((SourceTypeBinding) ((ReferenceBinding) this._receiver.resolvedType)
                .getRealClass());
        if (SyntheticBaseCallSurrogate.isBindingForCallinMethodInherited(callinMethod)) {
            ReferenceBinding currentRole = callinMethod.declaringClass;
            while (surrogate == null && ((currentRole = currentRole.superclass()) != null)) {
                surrogate = receiverClass
                        .getExactMethod(SyntheticBaseCallSurrogate.genSurrogateName(this.sourceSelector,
                                currentRole.sourceName(), callinMethod.isStatic()), sendparams, null);
            }
        } else {
            surrogate = receiverClass.addSyntheticBaseCallSurrogate(callinMethod);
        }
    }
    this._sendOrig.binding = surrogate;
    this._sendOrig.actualReceiverType = this._receiver.resolvedType;
    this._sendOrig.constant = Constant.NotAConstant;
    this.resolvedType = this._sendOrig.resolvedType = MethodModel.getReturnType(this._sendOrig.binding);
}