List of usage examples for org.eclipse.jdt.internal.compiler.lookup Scope substitute
public static TypeBinding[] substitute(Substitution substitution, TypeBinding[] originalTypes)
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()); }