List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding isInterface
public boolean isInterface()
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.TypeDeclarationLocator.java
License:Open Source License
public int resolveLevel(Binding binding) { if (binding == null) return INACCURATE_MATCH; if (!(binding instanceof TypeBinding)) return IMPOSSIBLE_MATCH; TypeBinding type = (TypeBinding) binding; switch (this.pattern.typeSuffix) { case CLASS_SUFFIX: if (!type.isClass()) return IMPOSSIBLE_MATCH; break;/*from w ww. j a v a2s. com*/ case CLASS_AND_INTERFACE_SUFFIX: if (!(type.isClass() || (type.isInterface() && !type.isAnnotationType()))) return IMPOSSIBLE_MATCH; break; case CLASS_AND_ENUM_SUFFIX: if (!(type.isClass() || type.isEnum())) return IMPOSSIBLE_MATCH; break; case INTERFACE_SUFFIX: if (!type.isInterface() || type.isAnnotationType()) return IMPOSSIBLE_MATCH; break; case INTERFACE_AND_ANNOTATION_SUFFIX: if (!(type.isInterface() || type.isAnnotationType())) return IMPOSSIBLE_MATCH; break; case ENUM_SUFFIX: if (!type.isEnum()) return IMPOSSIBLE_MATCH; break; case ANNOTATION_TYPE_SUFFIX: if (!type.isAnnotationType()) return IMPOSSIBLE_MATCH; break; case TYPE_SUFFIX: // nothing } // fully qualified name if (this.pattern instanceof QualifiedTypeDeclarationPattern) { QualifiedTypeDeclarationPattern qualifiedPattern = (QualifiedTypeDeclarationPattern) this.pattern; return resolveLevelForType(qualifiedPattern.simpleName, qualifiedPattern.qualification, type); } else { char[] enclosingTypeName = this.pattern.enclosingTypeNames == null ? null : CharOperation.concatWith(this.pattern.enclosingTypeNames, '.'); return resolveLevelForType(this.pattern.simpleName, this.pattern.pkg, enclosingTypeName, type); } }
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.TypeReferenceLocator.java
License:Open Source License
protected int resolveLevelForType(TypeBinding typeBinding) { if (typeBinding == null || !typeBinding.isValidBinding()) { if (this.pattern.typeSuffix != TYPE_SUFFIX) return INACCURATE_MATCH; } else {//from www . j a v a 2 s . c o m switch (this.pattern.typeSuffix) { case CLASS_SUFFIX: if (!typeBinding.isClass()) return IMPOSSIBLE_MATCH; break; case CLASS_AND_INTERFACE_SUFFIX: if (!(typeBinding.isClass() || (typeBinding.isInterface() && !typeBinding.isAnnotationType()))) return IMPOSSIBLE_MATCH; break; case CLASS_AND_ENUM_SUFFIX: if (!(typeBinding.isClass() || typeBinding.isEnum())) return IMPOSSIBLE_MATCH; break; case INTERFACE_SUFFIX: if (!typeBinding.isInterface() || typeBinding.isAnnotationType()) return IMPOSSIBLE_MATCH; break; case INTERFACE_AND_ANNOTATION_SUFFIX: if (!(typeBinding.isInterface() || typeBinding.isAnnotationType())) return IMPOSSIBLE_MATCH; break; case ENUM_SUFFIX: if (!typeBinding.isEnum()) return IMPOSSIBLE_MATCH; break; case ANNOTATION_TYPE_SUFFIX: if (!typeBinding.isAnnotationType()) return IMPOSSIBLE_MATCH; break; case TYPE_SUFFIX: // nothing } } return resolveLevelForType(this.pattern.simpleName, this.pattern.qualification, this.pattern.getTypeArguments(), 0, typeBinding); }
From source file:lombok.eclipse.handlers.HandleListenerSupport.java
License:Open Source License
@Override public void handle(final AnnotationValues<ListenerSupport> annotation, final Annotation source, final EclipseNode annotationNode) { EclipseType type = EclipseType.typeOf(annotationNode, source); if (type.isAnnotation() || type.isInterface()) { annotationNode.addError(canBeUsedOnClassAndEnumOnly(ListenerSupport.class)); return;//from w ww . j a v a2 s .c om } List<Object> listenerInterfaces = annotation.getActualExpressions("value"); if (listenerInterfaces.isEmpty()) { annotationNode.addError(String.format("@%s has no effect since no interface types were specified.", ListenerSupport.class.getName())); return; } for (Object listenerInterface : listenerInterfaces) { if (listenerInterface instanceof ClassLiteralAccess) { TypeBinding binding = ((ClassLiteralAccess) listenerInterface).type .resolveType(type.get().initializerScope); if (binding == null) continue; if (!binding.isInterface()) { annotationNode.addWarning(String.format("@%s works only with interfaces. %s was skipped", ListenerSupport.class.getName(), As.string(binding.readableName()))); continue; } handler.addListenerField(type, binding); handler.addAddListenerMethod(type, binding); handler.addRemoveListenerMethod(type, binding); addFireListenerMethods(type, binding); } } type.editor().rebuild(); }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
/** * Connect type variable supertypes, and returns true if no problem was detected * @param typeParameters/*from ww w.j ava 2 s . c o m*/ * @param checkForErasedCandidateCollisions */ protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) { /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 - We used to not bother with connecting type variables if source level is < 1.5. This creates problems in the reconciler if a 1.4 project references the generified API of a 1.5 project. The "current" project's source level cannot decide this question for some other project. Now, if we see type parameters at all, we assume that the concerned java element has some legitimate business with them. */ if (typeParameters == null || typeParameters.length == 0) return true; Map invocations = new HashMap(2); boolean noProblems = true; // preinitializing each type variable for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) { TypeParameter typeParameter = typeParameters[i]; TypeVariableBinding typeVariable = typeParameter.binding; if (typeVariable == null) return false; typeVariable.superclass = getJavaLangObject(); typeVariable.superInterfaces = Binding.NO_SUPERINTERFACES; // set firstBound to the binding of the first explicit bound in parameter declaration typeVariable.firstBound = null; // first bound used to compute erasure } nextVariable: for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) { TypeParameter typeParameter = typeParameters[i]; TypeVariableBinding typeVariable = typeParameter.binding; TypeReference typeRef = typeParameter.type; if (typeRef == null) continue nextVariable; boolean isFirstBoundTypeVariable = false; TypeBinding superType = this.kind == METHOD_SCOPE ? typeRef.resolveType((BlockScope) this, false/*no bound check*/) : typeRef.resolveType((ClassScope) this); if (superType == null) { typeVariable.tagBits |= TagBits.HierarchyHasProblems; } else { typeRef.resolvedType = superType; // hold onto the problem type firstBound: { switch (superType.kind()) { case Binding.ARRAY_TYPE: problemReporter().boundCannotBeArray(typeRef, superType); typeVariable.tagBits |= TagBits.HierarchyHasProblems; break firstBound; // do not keep first bound case Binding.TYPE_PARAMETER: isFirstBoundTypeVariable = true; TypeVariableBinding varSuperType = (TypeVariableBinding) superType; if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) { if (compilerOptions().complianceLevel <= ClassFileConstants.JDK1_6) { problemReporter().forwardTypeVariableReference(typeParameter, varSuperType); typeVariable.tagBits |= TagBits.HierarchyHasProblems; break firstBound; // do not keep first bound } } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=335751 if (compilerOptions().complianceLevel > ClassFileConstants.JDK1_6) { if (typeVariable.rank >= varSuperType.rank && varSuperType.declaringElement == typeVariable.declaringElement) { SimpleSet set = new SimpleSet(typeParameters.length); set.add(typeVariable); ReferenceBinding superBinding = varSuperType; while (superBinding instanceof TypeVariableBinding) { if (set.includes(superBinding)) { problemReporter().hierarchyCircularity(typeVariable, varSuperType, typeRef); typeVariable.tagBits |= TagBits.HierarchyHasProblems; break firstBound; // do not keep first bound } else { set.add(superBinding); superBinding = ((TypeVariableBinding) superBinding).superclass; } } } } break; default: if (((ReferenceBinding) superType).isFinal()) { problemReporter().finalVariableBound(typeVariable, typeRef); } break; } ReferenceBinding superRefType = (ReferenceBinding) superType; if (!superType.isInterface()) { typeVariable.superclass = superRefType; } else { typeVariable.superInterfaces = new ReferenceBinding[] { superRefType }; } typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences; typeVariable.firstBound = superRefType; // first bound used to compute erasure } } TypeReference[] boundRefs = typeParameter.bounds; if (boundRefs != null) { nextBound: for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) { typeRef = boundRefs[j]; superType = this.kind == METHOD_SCOPE ? typeRef.resolveType((BlockScope) this, false) : typeRef.resolveType((ClassScope) this); if (superType == null) { typeVariable.tagBits |= TagBits.HierarchyHasProblems; continue nextBound; } else { typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences; boolean didAlreadyComplain = !typeRef.resolvedType.isValidBinding(); if (isFirstBoundTypeVariable && j == 0) { problemReporter().noAdditionalBoundAfterTypeVariable(typeRef); typeVariable.tagBits |= TagBits.HierarchyHasProblems; didAlreadyComplain = true; //continue nextBound; - keep these bounds to minimize secondary errors } else if (superType.isArrayType()) { if (!didAlreadyComplain) { problemReporter().boundCannotBeArray(typeRef, superType); typeVariable.tagBits |= TagBits.HierarchyHasProblems; } continue nextBound; } else { if (!superType.isInterface()) { if (!didAlreadyComplain) { problemReporter().boundMustBeAnInterface(typeRef, superType); typeVariable.tagBits |= TagBits.HierarchyHasProblems; } continue nextBound; } } // check against superclass if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) { if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) { continue nextBound; } } // check against superinterfaces ReferenceBinding superRefType = (ReferenceBinding) superType; for (int index = typeVariable.superInterfaces.length; --index >= 0;) { ReferenceBinding previousInterface = typeVariable.superInterfaces[index]; if (previousInterface == superRefType) { problemReporter().duplicateBounds(typeRef, superType); typeVariable.tagBits |= TagBits.HierarchyHasProblems; continue nextBound; } if (checkForErasedCandidateCollisions) { if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) { continue nextBound; } } } int size = typeVariable.superInterfaces.length; System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size); typeVariable.superInterfaces[size] = superRefType; } } } noProblems &= (typeVariable.tagBits & TagBits.HierarchyHasProblems) == 0; } return noProblems; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
private TypeBinding lowerUpperBound(TypeBinding[] types, List lubStack) { int typeLength = types.length; if (typeLength == 1) { TypeBinding type = types[0];//ww w . java 2 s . c o m return type == null ? TypeBinding.VOID : type; } // cycle detection int stackLength = lubStack.size(); nextLubCheck: for (int i = 0; i < stackLength; i++) { TypeBinding[] lubTypes = (TypeBinding[]) lubStack.get(i); int lubTypeLength = lubTypes.length; if (lubTypeLength < typeLength) continue nextLubCheck; nextTypeCheck: for (int j = 0; j < typeLength; j++) { TypeBinding type = types[j]; if (type == null) continue nextTypeCheck; // ignore for (int k = 0; k < lubTypeLength; k++) { TypeBinding lubType = lubTypes[k]; if (lubType == null) continue; // ignore if (lubType == type || lubType.isEquivalentTo(type)) continue nextTypeCheck; // type found, jump to next one } continue nextLubCheck; // type not found in current lubTypes } // all types are included in some lub, cycle detected - stop recursion by answering special value (int) return TypeBinding.INT; } lubStack.add(types); Map invocations = new HashMap(1); TypeBinding[] mecs = minimalErasedCandidates(types, invocations); if (mecs == null) return null; int length = mecs.length; if (length == 0) return TypeBinding.VOID; int count = 0; TypeBinding firstBound = null; int commonDim = -1; for (int i = 0; i < length; i++) { TypeBinding mec = mecs[i]; if (mec == null) continue; mec = leastContainingInvocation(mec, invocations.get(mec), lubStack); if (mec == null) return null; int dim = mec.dimensions(); if (commonDim == -1) { commonDim = dim; } else if (dim != commonDim) { // not all types have same dimension return null; } if (firstBound == null && !mec.leafComponentType().isInterface()) firstBound = mec.leafComponentType(); mecs[count++] = mec; // recompact them to the front } switch (count) { case 0: return TypeBinding.VOID; case 1: return mecs[0]; case 2: if ((commonDim == 0 ? mecs[1].id : mecs[1].leafComponentType().id) == TypeIds.T_JavaLangObject) return mecs[0]; if ((commonDim == 0 ? mecs[0].id : mecs[0].leafComponentType().id) == TypeIds.T_JavaLangObject) return mecs[1]; } TypeBinding[] otherBounds = new TypeBinding[count - 1]; int rank = 0; for (int i = 0; i < count; i++) { TypeBinding mec = commonDim == 0 ? mecs[i] : mecs[i].leafComponentType(); if (mec.isInterface()) { otherBounds[rank++] = mec; } } TypeBinding intersectionType = environment().createWildcard(null, 0, firstBound, otherBounds, Wildcard.EXTENDS); return commonDim == 0 ? intersectionType : environment().createArrayType(intersectionType, commonDim); }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
/** * Returns the most specific set of types compatible with all given types. * (i.e. most specific common super types) * If no types is given, will return an empty array. If not compatible * reference type is found, returns null. In other cases, will return an array * of minimal erased types, where some nulls may appear (and must simply be * ignored)./* w w w .ja va 2s . co m*/ */ protected TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) { int length = types.length; int indexOfFirst = -1, actualLength = 0; for (int i = 0; i < length; i++) { TypeBinding type = types[i]; if (type == null) continue; if (type.isBaseType()) return null; if (indexOfFirst < 0) indexOfFirst = i; actualLength++; } switch (actualLength) { case 0: return Binding.NO_TYPES; case 1: return types; } TypeBinding firstType = types[indexOfFirst]; if (firstType.isBaseType()) return null; // record all supertypes of type // intersect with all supertypes of otherType ArrayList typesToVisit = new ArrayList(5); int dim = firstType.dimensions(); TypeBinding leafType = firstType.leafComponentType(); // do not allow type variables/intersection types to match with erasures for free TypeBinding firstErasure; switch (leafType.kind()) { case Binding.PARAMETERIZED_TYPE: case Binding.RAW_TYPE: case Binding.ARRAY_TYPE: firstErasure = firstType.erasure(); break; default: firstErasure = firstType; break; } if (firstErasure != firstType) { allInvocations.put(firstErasure, firstType); } typesToVisit.add(firstType); int max = 1; ReferenceBinding currentType; for (int i = 0; i < max; i++) { TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i); dim = typeToVisit.dimensions(); if (dim > 0) { leafType = typeToVisit.leafComponentType(); switch (leafType.id) { case TypeIds.T_JavaLangObject: if (dim > 1) { // Object[][] supertype is Object[] TypeBinding elementType = ((ArrayBinding) typeToVisit).elementsType(); if (!typesToVisit.contains(elementType)) { typesToVisit.add(elementType); max++; } continue; } //$FALL-THROUGH$ case TypeIds.T_byte: case TypeIds.T_short: case TypeIds.T_char: case TypeIds.T_boolean: case TypeIds.T_int: case TypeIds.T_long: case TypeIds.T_float: case TypeIds.T_double: TypeBinding superType = getJavaIoSerializable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangCloneable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangObject(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } continue; default: } typeToVisit = leafType; } currentType = (ReferenceBinding) typeToVisit; if (currentType.isCapture()) { TypeBinding firstBound = ((CaptureBinding) currentType).firstBound; if (firstBound != null && firstBound.isArrayType()) { TypeBinding superType = dim == 0 ? firstBound : (TypeBinding) environment().createArrayType(firstBound, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (firstBound.isTypeVariable() || firstBound.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } continue; } } // inject super interfaces prior to superclass ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (itsInterfaces != null) { // can be null during code assist operations that use LookupEnvironment.completeTypeBindings(parsedUnit, buildFieldsAndMethods) for (int j = 0, count = itsInterfaces.length; j < count; j++) { TypeBinding itsInterface = itsInterfaces[j]; TypeBinding superType = dim == 0 ? itsInterface : (TypeBinding) environment().createArrayType(itsInterface, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsInterface.isTypeVariable() || itsInterface.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } TypeBinding itsSuperclass = currentType.superclass(); if (itsSuperclass != null) { TypeBinding superType = dim == 0 ? itsSuperclass : (TypeBinding) environment().createArrayType(itsSuperclass, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsSuperclass.isTypeVariable() || itsSuperclass.isWildcard() /*&& !itsSuperclass.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } int superLength = typesToVisit.size(); TypeBinding[] erasedSuperTypes = new TypeBinding[superLength]; int rank = 0; for (Iterator iter = typesToVisit.iterator(); iter.hasNext();) { TypeBinding type = (TypeBinding) iter.next(); leafType = type.leafComponentType(); erasedSuperTypes[rank++] = (leafType.isTypeVariable() || leafType.isWildcard() /*&& !leafType.isCapture()*/) ? type : type.erasure(); } // intersecting first type supertypes with other types' ones, nullifying non matching supertypes int remaining = superLength; nextOtherType: for (int i = indexOfFirst + 1; i < length; i++) { TypeBinding otherType = types[i]; if (otherType == null) continue nextOtherType; if (otherType.isArrayType()) { nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType; TypeBinding match; if ((match = otherType.findSuperTypeOriginatingFrom(erasedSuperType)) == null) { erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } continue nextOtherType; } nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null) continue nextSuperType; TypeBinding match; if (erasedSuperType == otherType || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) { match = erasedSuperType; } else { if (erasedSuperType.isArrayType()) { match = null; } else { match = otherType.findSuperTypeOriginatingFrom(erasedSuperType); } if (match == null) { // incompatible super type erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } } // eliminate non minimal super types if (remaining > 1) { nextType: for (int i = 0; i < superLength; i++) { TypeBinding erasedSuperType = erasedSuperTypes[i]; if (erasedSuperType == null) continue nextType; nextOtherType: for (int j = 0; j < superLength; j++) { if (i == j) continue nextOtherType; TypeBinding otherType = erasedSuperTypes[j]; if (otherType == null) continue nextOtherType; if (erasedSuperType instanceof ReferenceBinding) { if (otherType.id == TypeIds.T_JavaLangObject && erasedSuperType.isInterface()) continue nextOtherType; // keep Object for an interface if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } else if (erasedSuperType.isArrayType()) { if (otherType.isArrayType() // keep Object[...] for an interface array (same dimensions) && otherType.leafComponentType().id == TypeIds.T_JavaLangObject && otherType.dimensions() == erasedSuperType.dimensions() && erasedSuperType.leafComponentType().isInterface()) continue nextOtherType; if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } } } } return erasedSuperTypes; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
public MethodBinding getStaticFactory(ReferenceBinding allocationType, ReferenceBinding originalEnclosingType, TypeBinding[] argumentTypes, final InvocationSite allocationSite) { TypeVariableBinding[] classTypeVariables = allocationType.typeVariables(); int classTypeVariablesArity = classTypeVariables.length; MethodBinding[] methods = allocationType.getMethods(TypeConstants.INIT, argumentTypes.length); MethodBinding[] staticFactories = new MethodBinding[methods.length]; int sfi = 0;// w w w .jav a2 s. com for (int i = 0, length = methods.length; i < length; i++) { MethodBinding method = methods[i]; int paramLength = method.parameters.length; boolean isVarArgs = method.isVarargs(); if (argumentTypes.length != paramLength) if (!isVarArgs || argumentTypes.length < paramLength - 1) continue; // incompatible TypeVariableBinding[] methodTypeVariables = method.typeVariables(); int methodTypeVariablesArity = methodTypeVariables.length; MethodBinding staticFactory = new MethodBinding(method.modifiers | ClassFileConstants.AccStatic, TypeConstants.SYNTHETIC_STATIC_FACTORY, null, null, null, method.declaringClass); staticFactory.typeVariables = new TypeVariableBinding[classTypeVariablesArity + methodTypeVariablesArity]; final SimpleLookupTable map = new SimpleLookupTable(classTypeVariablesArity + methodTypeVariablesArity); // Rename each type variable T of the type to T' final LookupEnvironment environment = environment(); for (int j = 0; j < classTypeVariablesArity; j++) { map.put(classTypeVariables[j], staticFactory.typeVariables[j] = new TypeVariableBinding( CharOperation.concat(classTypeVariables[j].sourceName, "'".toCharArray()), //$NON-NLS-1$ staticFactory, j, environment)); } // Rename each type variable U of method U to U''. for (int j = classTypeVariablesArity, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) { map.put(methodTypeVariables[j - classTypeVariablesArity], (staticFactory.typeVariables[j] = new TypeVariableBinding( CharOperation.concat(methodTypeVariables[j - classTypeVariablesArity].sourceName, "''".toCharArray()), //$NON-NLS-1$ staticFactory, j, environment))); } ReferenceBinding enclosingType = originalEnclosingType; while (enclosingType != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=345968 if (enclosingType.kind() == Binding.PARAMETERIZED_TYPE) { final ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) enclosingType; final ReferenceBinding genericType = parameterizedType.genericType(); TypeVariableBinding[] enclosingClassTypeVariables = genericType.typeVariables(); int enclosingClassTypeVariablesArity = enclosingClassTypeVariables.length; for (int j = 0; j < enclosingClassTypeVariablesArity; j++) { map.put(enclosingClassTypeVariables[j], parameterizedType.arguments[j]); } } enclosingType = enclosingType.enclosingType(); } final Scope scope = this; Substitution substitution = new Substitution() { public LookupEnvironment environment() { return scope.environment(); } public boolean isRawSubstitution() { return false; } public TypeBinding substitute(TypeVariableBinding typeVariable) { TypeBinding retVal = (TypeBinding) map.get(typeVariable); return retVal != null ? retVal : typeVariable; } }; // initialize new variable bounds for (int j = 0, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) { TypeVariableBinding originalVariable = j < classTypeVariablesArity ? classTypeVariables[j] : methodTypeVariables[j - classTypeVariablesArity]; TypeBinding substitutedType = (TypeBinding) map.get(originalVariable); if (substitutedType instanceof TypeVariableBinding) { TypeVariableBinding substitutedVariable = (TypeVariableBinding) substitutedType; TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass); ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces); if (originalVariable.firstBound != null) { substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass ? substitutedSuperclass // could be array type or interface : substitutedInterfaces[0]; } switch (substitutedSuperclass.kind()) { case Binding.ARRAY_TYPE: substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null); substitutedVariable.superInterfaces = substitutedInterfaces; break; default: if (substitutedSuperclass.isInterface()) { substitutedVariable.superclass = environment .getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null); int interfaceCount = substitutedInterfaces.length; System.arraycopy(substitutedInterfaces, 0, substitutedInterfaces = new ReferenceBinding[interfaceCount + 1], 1, interfaceCount); substitutedInterfaces[0] = (ReferenceBinding) substitutedSuperclass; substitutedVariable.superInterfaces = substitutedInterfaces; } else { substitutedVariable.superclass = (ReferenceBinding) substitutedSuperclass; // typeVar was extending other typeVar which got substituted with interface substitutedVariable.superInterfaces = substitutedInterfaces; } } } } TypeVariableBinding[] returnTypeParameters = new TypeVariableBinding[classTypeVariablesArity]; for (int j = 0; j < classTypeVariablesArity; j++) { returnTypeParameters[j] = (TypeVariableBinding) map.get(classTypeVariables[j]); } staticFactory.returnType = environment.createParameterizedType(allocationType, returnTypeParameters, allocationType.enclosingType()); staticFactory.parameters = Scope.substitute(substitution, method.parameters); staticFactory.thrownExceptions = Scope.substitute(substitution, method.thrownExceptions); if (staticFactory.thrownExceptions == null) { staticFactory.thrownExceptions = Binding.NO_EXCEPTIONS; } staticFactories[sfi++] = new ParameterizedMethodBinding( (ParameterizedTypeBinding) environment.convertToParameterizedType(staticFactory.declaringClass), staticFactory); } if (sfi == 0) return null; if (sfi != methods.length) { System.arraycopy(staticFactories, 0, staticFactories = new MethodBinding[sfi], 0, sfi); } MethodBinding[] compatible = new MethodBinding[sfi]; int compatibleIndex = 0; for (int i = 0; i < sfi; i++) { MethodBinding compatibleMethod = computeCompatibleMethod(staticFactories[i], argumentTypes, allocationSite); if (compatibleMethod != null) { if (compatibleMethod.isValidBinding()) compatible[compatibleIndex++] = compatibleMethod; } } if (compatibleIndex == 0) { return null; } MethodBinding[] visible = new MethodBinding[compatibleIndex]; int visibleIndex = 0; for (int i = 0; i < compatibleIndex; i++) { MethodBinding method = compatible[i]; if (method.canBeSeenBy(allocationSite, this)) visible[visibleIndex++] = method; } if (visibleIndex == 0) { return null; } return visibleIndex == 1 ? visible[0] : mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, allocationSite, allocationType); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.ConstantPoolObjectMapper.java
License:Open Source License
/** * Map a type binding and convert it to a UTF8-Object. * @param typeBinding/* w w w. jav a 2s . c om*/ * @param useGenerics should type parameters be respected (else use erasure) * @return ConstantPoolObject of type Utf8Tag */ public ConstantPoolObject mapTypeUtf8(TypeBinding typeBinding, boolean useGenerics) { //System.out.println("Sign of "+typeBinding+"="+new String(typeBinding.signature())); char[] prefix = null; if (typeBinding.isArrayType()) { // need to disassemble arrays, because we want to analyze the element type: ArrayBinding array = (ArrayBinding) typeBinding; prefix = new char[array.dimensions()]; Arrays.fill(prefix, '['); typeBinding = array.leafComponentType; } if (typeBinding.isClass() || typeBinding.isInterface()) { ConstantPoolObject clazzCPO = new ConstantPoolObject(ClassTag, mapClass(this._srcMethod, typeBinding, getTeam(this._dstMethod))); typeBinding = clazzCPO.getClassObject(); } char[] signature = useGenerics ? typeBinding.genericTypeSignature() : typeBinding.signature(); if (prefix != null) signature = CharOperation.concat(prefix, signature); return new ConstantPoolObject(Utf8Tag, signature); }