Example usage for org.eclipse.jdt.internal.compiler.lookup Scope substitute

List of usage examples for org.eclipse.jdt.internal.compiler.lookup Scope substitute

Introduction

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

Prototype

public static TypeBinding[] substitute(Substitution substitution, TypeBinding[] originalTypes) 

Source Link

Document

Returns an array of types, where original types got substituted given a substitution.

Usage

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

License:Open Source License

MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
    if (inheritedMethod == null)
        return null;
    if (currentMethod.parameters.length != inheritedMethod.parameters.length)
        return null; // no match

    // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
    if (currentMethod.declaringClass instanceof BinaryTypeBinding)
        ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod);
    if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
        ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod);

    TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables;
    int inheritedLength = inheritedTypeVariables.length;
    if (inheritedLength == 0)
        return inheritedMethod; // no substitution needed
    TypeVariableBinding[] typeVariables = currentMethod.typeVariables;
    int length = typeVariables.length;
    if (length == 0)
        return inheritedMethod.asRawMethod(this.environment);
    if (length != inheritedLength)
        return inheritedMethod; // no match JLS 8.4.2

    // interface I { <T> void foo(T t); }
    // class X implements I { public <T extends I> void foo(T t) {} }
    // for the above case, we do not want to answer the substitute method since its not a match
    TypeBinding[] arguments = new TypeBinding[length];
    System.arraycopy(typeVariables, 0, arguments, 0, length);
    ParameterizedGenericMethodBinding substitute = this.environment
            .createParameterizedGenericMethod(inheritedMethod, arguments);
    for (int i = 0; i < inheritedLength; i++) {
        TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i];
        TypeBinding argument = arguments[i];
        if (argument instanceof TypeVariableBinding) {
            TypeVariableBinding typeVariable = (TypeVariableBinding) argument;
            if (typeVariable.firstBound == inheritedTypeVariable.firstBound) {
                if (typeVariable.firstBound == null)
                    continue; // both are null
            } else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) {
                if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass())
                    return inheritedMethod; // not a match
            }//from ww  w.  j a  v a 2 s  .  co m
            if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass)
                return inheritedMethod; // not a match
            int interfaceLength = inheritedTypeVariable.superInterfaces.length;
            ReferenceBinding[] interfaces = typeVariable.superInterfaces;
            if (interfaceLength != interfaces.length)
                return inheritedMethod; // not a match
            // TODO (kent) another place where we expect the superinterfaces to be in the exact same order
            next: for (int j = 0; j < interfaceLength; j++) {
                TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]);
                for (int k = 0; k < interfaceLength; k++)
                    if (superType == interfaces[k])
                        continue next;
                return inheritedMethod; // not a match
            }
        } else if (inheritedTypeVariable.boundCheck(substitute, argument) != TypeConstants.OK) {
            return inheritedMethod;
        }
    }
    return substitute;
}

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. ja v  a 2  s.c  o m
    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.statemachine.copyinheritance.TypeLevel.java

License:Open Source License

/**
 * Merge super interfaces from implicitly inherited role and current.
 * Adjust all role types to the current team, except the link between
 * a role and its tsuper version (adjust that to the super-team).
 *
 * @param srcRole/*from w ww.  j  a va 2  s .  c o  m*/
 * @param destRole
 */
static void mergeSuperinterfaces(ReferenceBinding superTeam, ReferenceBinding srcRole,
        SourceTypeBinding destRole) {
    ReferenceBinding[] srcSuperIfcs = srcRole.superInterfaces();
    if (srcSuperIfcs == null || srcSuperIfcs.length == 0) {
        return;
    }

    // for avoiding duplicates:
    HashSet<ReferenceBinding> newInterfaces = new HashSet<ReferenceBinding>();
    if (destRole.superInterfaces != null) {
        for (int i = 0; i < destRole.superInterfaces.length; i++) {
            newInterfaces.add(destRole.superInterfaces[i]);
        }
    }

    // merge
    ReferenceBinding destTeam = destRole.enclosingType();
    for (int i = 0; i < srcSuperIfcs.length; i++) {
        ReferenceBinding newSuperIfc = srcSuperIfcs[i];
        if (CharOperation.equals(srcSuperIfcs[i].internalName(), destRole.internalName())) {
            continue; // the link between class part and interface part.
        } else {
            newSuperIfc = destTeam.getMemberType(newSuperIfc.internalName());
            if (newSuperIfc == null)
                newSuperIfc = srcSuperIfcs[i]; // not a role of destTeam: restore
        }
        if (newSuperIfc == null)
            throw new InternalCompilerError("superinterface not found for " //$NON-NLS-1$
                    + new String(destRole.internalName()) + ": " //$NON-NLS-1$
                    + new String(srcSuperIfcs[i].readableName()));
        if (superTeam.isParameterizedType())
            newSuperIfc = (ReferenceBinding) Scope.substitute((ParameterizedTypeBinding) superTeam,
                    newSuperIfc);
        newInterfaces.add(newSuperIfc);
        destRole.scope.compilationUnitScope().recordSuperTypeReference(newSuperIfc);
    }
    // write back into array:
    System.arraycopy(newInterfaces.toArray(), 0,
            destRole.superInterfaces = new ReferenceBinding[newInterfaces.size()], 0, newInterfaces.size());
}