List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding isTypeVariable
public boolean isTypeVariable()
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.MethodLocator.java
License:Open Source License
protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) { if (!matchesName(this.pattern.selector, method.selector)) return IMPOSSIBLE_MATCH; int level = ACCURATE_MATCH; // look at return type only if declaring type is not specified if (this.pattern.declaringSimpleName == null) { // TODO (frederic) use this call to refine accuracy on return type // int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, this.pattern.returnTypeArguments, 0, method.returnType); int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, method.returnType);//from w ww .j av a2s.c o m if (level > newLevel) { if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; level = newLevel; // can only be downgraded } } // parameter types int parameterCount = this.pattern.parameterSimpleNames == null ? -1 : this.pattern.parameterSimpleNames.length; if (parameterCount > -1) { // global verification if (method.parameters == null) return INACCURATE_MATCH; if (parameterCount != method.parameters.length) return IMPOSSIBLE_MATCH; if (!method.isValidBinding() && ((ProblemMethodBinding) method).problemId() == ProblemReasons.Ambiguous) { // return inaccurate match for ambiguous call (bug 80890) return INACCURATE_MATCH; } boolean foundTypeVariable = false; // verify each parameter for (int i = 0; i < parameterCount; i++) { TypeBinding argType = method.parameters[i]; int newLevel = IMPOSSIBLE_MATCH; if (argType.isMemberType()) { // only compare source name for member type (bug 41018) newLevel = CharOperation.match(this.pattern.parameterSimpleNames[i], argType.sourceName(), this.isCaseSensitive) ? ACCURATE_MATCH : IMPOSSIBLE_MATCH; } else { // TODO (frederic) use this call to refine accuracy on parameter types // newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType); newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], argType); } if (level > newLevel) { if (newLevel == IMPOSSIBLE_MATCH) { if (skipImpossibleArg) { // Do not consider match as impossible while finding declarations and source level >= 1.5 // (see bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763) newLevel = level; } else if (argType.isTypeVariable()) { newLevel = level; foundTypeVariable = true; } else { return IMPOSSIBLE_MATCH; } } level = newLevel; // can only be downgraded } } if (foundTypeVariable) { if (!method.isStatic() && !method.isPrivate()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836, No point in textually comparing type variables, captures etc with concrete types. MethodBinding focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern); if (focusMethodBinding != null) { if (matchOverriddenMethod(focusMethodBinding.declaringClass, focusMethodBinding, method)) { return ACCURATE_MATCH; } } } return IMPOSSIBLE_MATCH; } } return level; }
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.PatternLocator.java
License:Open Source License
/** * Returns whether the given type binding matches the given qualified pattern. * Returns ACCURATE_MATCH if it does.//from w ww . ja v a2 s .c om * Returns INACCURATE_MATCH if resolve failed. * Returns IMPOSSIBLE_MATCH if it doesn't. */ protected int resolveLevelForType(char[] qualifiedPattern, TypeBinding type) { if (qualifiedPattern == null) return ACCURATE_MATCH; if (type == null || !type.isValidBinding()) return INACCURATE_MATCH; // Type variable cannot be specified through pattern => this kind of binding cannot match it (see bug 79803) if (type.isTypeVariable()) return IMPOSSIBLE_MATCH; // NOTE: if case insensitive search then qualifiedPattern is assumed to be lowercase char[] qualifiedPackageName = type.qualifiedPackageName(); char[] qualifiedSourceName = qualifiedSourceName(type); char[] fullyQualifiedTypeName = qualifiedPackageName.length == 0 ? qualifiedSourceName : CharOperation.concat(qualifiedPackageName, qualifiedSourceName, '.'); return CharOperation.match(qualifiedPattern, fullyQualifiedTypeName, this.isCaseSensitive) ? ACCURATE_MATCH : IMPOSSIBLE_MATCH; }
From source file:com.redhat.ceylon.eclipse.core.model.mirror.UnknownTypeMirror.java
License:Open Source License
public JDTType(TypeBinding type, IdentityHashMap<TypeBinding, JDTType> originatingTypes) { originatingTypes.put(type, this); // type params are not qualified if (type instanceof TypeVariableBinding) qualifiedName = new String(type.qualifiedSourceName()); else// ww w . j a v a2s .c om qualifiedName = JDTUtils.getFullyQualifiedName(type); typeKind = findKind(type); isPrimitive = type.isBaseType() && type.id != TypeIds.T_void && type.id != TypeIds.T_null; isRaw = type.isRawType(); if (type instanceof ParameterizedTypeBinding && !(type instanceof RawTypeBinding)) { TypeBinding[] javaTypeArguments = ((ParameterizedTypeBinding) type).arguments; if (javaTypeArguments == null) { javaTypeArguments = new TypeBinding[0]; } typeArguments = new ArrayList<TypeMirror>(javaTypeArguments.length); for (TypeBinding typeArgument : javaTypeArguments) typeArguments.add(toTypeMirror(typeArgument, type, this, originatingTypes)); } else { typeArguments = Collections.emptyList(); } if (type instanceof ArrayBinding) { TypeBinding jdtComponentType = ((ArrayBinding) type).elementsType(); componentType = toTypeMirror(jdtComponentType, type, this, originatingTypes); } else { componentType = null; } if (type.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) type; if (wildcardBinding.boundKind == Wildcard.EXTENDS) { TypeBinding upperBoundBinding = wildcardBinding.bound; if (upperBoundBinding != null) { upperBound = toTypeMirror(upperBoundBinding, type, this, originatingTypes); } } } else if (type.isTypeVariable()) { TypeVariableBinding typeVariableBinding = (TypeVariableBinding) type; TypeBinding boundBinding = typeVariableBinding.firstBound; // TODO : we should confirm this if (boundBinding != null) { upperBound = toTypeMirror(boundBinding, type, this, originatingTypes); } } else { upperBound = null; } if (type.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) type; if (wildcardBinding.boundKind == Wildcard.SUPER) { TypeBinding lowerBoundBinding = wildcardBinding.bound; if (lowerBoundBinding != null) { lowerBound = toTypeMirror(lowerBoundBinding, type, this, originatingTypes); } } } if (type instanceof ParameterizedTypeBinding || type instanceof SourceTypeBinding || type instanceof BinaryTypeBinding) { ReferenceBinding refBinding = (ReferenceBinding) type; declaredClass = new JDTClass(refBinding, JDTModelLoader.toType(refBinding)); } if (type instanceof TypeVariableBinding) { typeParameter = new JDTTypeParameter((TypeVariableBinding) type, this, originatingTypes); } }
From source file:lombok.eclipse.handlers.EclipseHandlerUtil.java
License:Open Source License
public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) { int dims = binding.dimensions(); binding = binding.leafComponentType(); // Primitives char[] base = null; switch (binding.id) { case TypeIds.T_int: base = TypeConstants.INT;//from w ww. j a va 2s .c om break; case TypeIds.T_long: base = TypeConstants.LONG; break; case TypeIds.T_short: base = TypeConstants.SHORT; break; case TypeIds.T_byte: base = TypeConstants.BYTE; break; case TypeIds.T_double: base = TypeConstants.DOUBLE; break; case TypeIds.T_float: base = TypeConstants.FLOAT; break; case TypeIds.T_boolean: base = TypeConstants.BOOLEAN; break; case TypeIds.T_char: base = TypeConstants.CHAR; break; case TypeIds.T_void: base = TypeConstants.VOID; break; case TypeIds.T_null: return null; } if (base != null) { if (dims > 0) { TypeReference result = new ArrayTypeReference(base, dims, pos(pos)); setGeneratedBy(result, pos); return result; } TypeReference result = new SingleTypeReference(base, pos(pos)); setGeneratedBy(result, pos); return result; } if (binding.isAnonymousType()) { ReferenceBinding ref = (ReferenceBinding) binding; ReferenceBinding[] supers = ref.superInterfaces(); if (supers == null || supers.length == 0) supers = new ReferenceBinding[] { ref.superclass() }; if (supers[0] == null) { TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); setGeneratedBy(result, pos); return result; } return makeType(supers[0], pos, false); } if (binding instanceof CaptureBinding) { return makeType(((CaptureBinding) binding).wildcard, pos, allowCompound); } if (binding.isUnboundWildcard()) { if (!allowCompound) { TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); setGeneratedBy(result, pos); return result; } else { Wildcard out = new Wildcard(Wildcard.UNBOUND); setGeneratedBy(out, pos); out.sourceStart = pos.sourceStart; out.sourceEnd = pos.sourceEnd; return out; } } if (binding.isWildcard()) { WildcardBinding wildcard = (WildcardBinding) binding; if (wildcard.boundKind == Wildcard.EXTENDS) { if (!allowCompound) { return makeType(wildcard.bound, pos, false); } else { Wildcard out = new Wildcard(Wildcard.EXTENDS); setGeneratedBy(out, pos); out.bound = makeType(wildcard.bound, pos, false); out.sourceStart = pos.sourceStart; out.sourceEnd = pos.sourceEnd; return out; } } else if (allowCompound && wildcard.boundKind == Wildcard.SUPER) { Wildcard out = new Wildcard(Wildcard.SUPER); setGeneratedBy(out, pos); out.bound = makeType(wildcard.bound, pos, false); out.sourceStart = pos.sourceStart; out.sourceEnd = pos.sourceEnd; return out; } else { TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); setGeneratedBy(result, pos); return result; } } // Keep moving up via 'binding.enclosingType()' and gather generics from each binding. We stop after a local type, or a static type, or a top-level type. // Finally, add however many nullTypeArgument[] arrays as that are missing, inverse the list, toArray it, and use that as PTR's typeArgument argument. List<TypeReference[]> params = new ArrayList<TypeReference[]>(); /* Calculate generics */ { TypeBinding b = binding; while (true) { boolean isFinalStop = b.isLocalType() || !b.isMemberType() || b.enclosingType() == null; TypeReference[] tyParams = null; if (b instanceof ParameterizedTypeBinding) { ParameterizedTypeBinding paramized = (ParameterizedTypeBinding) b; if (paramized.arguments != null) { tyParams = new TypeReference[paramized.arguments.length]; for (int i = 0; i < tyParams.length; i++) { tyParams[i] = makeType(paramized.arguments[i], pos, true); } } } params.add(tyParams); if (isFinalStop) break; b = b.enclosingType(); } } char[][] parts; if (binding.isTypeVariable()) { parts = new char[][] { binding.shortReadableName() }; } else if (binding.isLocalType()) { parts = new char[][] { binding.sourceName() }; } else { String[] pkg = new String(binding.qualifiedPackageName()).split("\\."); String[] name = new String(binding.qualifiedSourceName()).split("\\."); if (pkg.length == 1 && pkg[0].isEmpty()) pkg = new String[0]; parts = new char[pkg.length + name.length][]; int ptr; for (ptr = 0; ptr < pkg.length; ptr++) parts[ptr] = pkg[ptr].toCharArray(); for (; ptr < pkg.length + name.length; ptr++) parts[ptr] = name[ptr - pkg.length].toCharArray(); } while (params.size() < parts.length) params.add(null); Collections.reverse(params); boolean isParamized = false; for (TypeReference[] tyParams : params) { if (tyParams != null) { isParamized = true; break; } } if (isParamized) { if (parts.length > 1) { TypeReference[][] typeArguments = params.toArray(new TypeReference[0][]); TypeReference result = new ParameterizedQualifiedTypeReference(parts, typeArguments, dims, poss(pos, parts.length)); setGeneratedBy(result, pos); return result; } TypeReference result = new ParameterizedSingleTypeReference(parts[0], params.get(0), dims, pos(pos)); setGeneratedBy(result, pos); return result; } if (dims > 0) { if (parts.length > 1) { TypeReference result = new ArrayQualifiedTypeReference(parts, dims, poss(pos, parts.length)); setGeneratedBy(result, pos); return result; } TypeReference result = new ArrayTypeReference(parts[0], dims, pos(pos)); setGeneratedBy(result, pos); return result; } if (parts.length > 1) { TypeReference result = new QualifiedTypeReference(parts, poss(pos, parts.length)); setGeneratedBy(result, pos); return result; } TypeReference result = new SingleTypeReference(parts[0], pos(pos)); setGeneratedBy(result, pos); return result; }
From source file:org.eclipse.jdt.internal.compiler.lookup.MethodVerifier15.java
License:Open Source License
boolean isAcceptableReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) { // called when currentMethod's return type is compatible with inheritedMethod's return type if (inheritedMethod.declaringClass.isRawType()) return true; // since the inheritedMethod comes from a raw type, the return type is always acceptable MethodBinding originalInherited = inheritedMethod.original(); TypeBinding originalInheritedReturnType = originalInherited.returnType.leafComponentType(); if (originalInheritedReturnType.isParameterizedTypeWithActualArguments()) return !currentMethod.returnType.leafComponentType().isRawType(); // raw types issue a warning if inherited is parameterized TypeBinding currentReturnType = currentMethod.returnType.leafComponentType(); switch (currentReturnType.kind()) { case Binding.TYPE_PARAMETER: if (currentReturnType == inheritedMethod.returnType.leafComponentType()) return true; //$FALL-THROUGH$ default:// ww w. ja va 2 s .c om if (originalInheritedReturnType.isTypeVariable()) if (((TypeVariableBinding) originalInheritedReturnType).declaringElement == originalInherited) return false; return true; } }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
/** * Returns the most specific set of types compatible with all given types. * (i.e. most specific common super types) * If no types is given, will return an empty array. If not compatible * reference type is found, returns null. In other cases, will return an array * of minimal erased types, where some nulls may appear (and must simply be * ignored)./*from ww w. j a va 2 s .c o m*/ */ protected TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) { int length = types.length; int indexOfFirst = -1, actualLength = 0; for (int i = 0; i < length; i++) { TypeBinding type = types[i]; if (type == null) continue; if (type.isBaseType()) return null; if (indexOfFirst < 0) indexOfFirst = i; actualLength++; } switch (actualLength) { case 0: return Binding.NO_TYPES; case 1: return types; } TypeBinding firstType = types[indexOfFirst]; if (firstType.isBaseType()) return null; // record all supertypes of type // intersect with all supertypes of otherType ArrayList typesToVisit = new ArrayList(5); int dim = firstType.dimensions(); TypeBinding leafType = firstType.leafComponentType(); // do not allow type variables/intersection types to match with erasures for free TypeBinding firstErasure; switch (leafType.kind()) { case Binding.PARAMETERIZED_TYPE: case Binding.RAW_TYPE: case Binding.ARRAY_TYPE: firstErasure = firstType.erasure(); break; default: firstErasure = firstType; break; } if (firstErasure != firstType) { allInvocations.put(firstErasure, firstType); } typesToVisit.add(firstType); int max = 1; ReferenceBinding currentType; for (int i = 0; i < max; i++) { TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i); dim = typeToVisit.dimensions(); if (dim > 0) { leafType = typeToVisit.leafComponentType(); switch (leafType.id) { case TypeIds.T_JavaLangObject: if (dim > 1) { // Object[][] supertype is Object[] TypeBinding elementType = ((ArrayBinding) typeToVisit).elementsType(); if (!typesToVisit.contains(elementType)) { typesToVisit.add(elementType); max++; } continue; } //$FALL-THROUGH$ case TypeIds.T_byte: case TypeIds.T_short: case TypeIds.T_char: case TypeIds.T_boolean: case TypeIds.T_int: case TypeIds.T_long: case TypeIds.T_float: case TypeIds.T_double: TypeBinding superType = getJavaIoSerializable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangCloneable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangObject(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } continue; default: } typeToVisit = leafType; } currentType = (ReferenceBinding) typeToVisit; if (currentType.isCapture()) { TypeBinding firstBound = ((CaptureBinding) currentType).firstBound; if (firstBound != null && firstBound.isArrayType()) { TypeBinding superType = dim == 0 ? firstBound : (TypeBinding) environment().createArrayType(firstBound, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (firstBound.isTypeVariable() || firstBound.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } continue; } } // inject super interfaces prior to superclass ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (itsInterfaces != null) { // can be null during code assist operations that use LookupEnvironment.completeTypeBindings(parsedUnit, buildFieldsAndMethods) for (int j = 0, count = itsInterfaces.length; j < count; j++) { TypeBinding itsInterface = itsInterfaces[j]; TypeBinding superType = dim == 0 ? itsInterface : (TypeBinding) environment().createArrayType(itsInterface, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsInterface.isTypeVariable() || itsInterface.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } TypeBinding itsSuperclass = currentType.superclass(); if (itsSuperclass != null) { TypeBinding superType = dim == 0 ? itsSuperclass : (TypeBinding) environment().createArrayType(itsSuperclass, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsSuperclass.isTypeVariable() || itsSuperclass.isWildcard() /*&& !itsSuperclass.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } int superLength = typesToVisit.size(); TypeBinding[] erasedSuperTypes = new TypeBinding[superLength]; int rank = 0; for (Iterator iter = typesToVisit.iterator(); iter.hasNext();) { TypeBinding type = (TypeBinding) iter.next(); leafType = type.leafComponentType(); erasedSuperTypes[rank++] = (leafType.isTypeVariable() || leafType.isWildcard() /*&& !leafType.isCapture()*/) ? type : type.erasure(); } // intersecting first type supertypes with other types' ones, nullifying non matching supertypes int remaining = superLength; nextOtherType: for (int i = indexOfFirst + 1; i < length; i++) { TypeBinding otherType = types[i]; if (otherType == null) continue nextOtherType; if (otherType.isArrayType()) { nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType; TypeBinding match; if ((match = otherType.findSuperTypeOriginatingFrom(erasedSuperType)) == null) { erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } continue nextOtherType; } nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null) continue nextSuperType; TypeBinding match; if (erasedSuperType == otherType || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) { match = erasedSuperType; } else { if (erasedSuperType.isArrayType()) { match = null; } else { match = otherType.findSuperTypeOriginatingFrom(erasedSuperType); } if (match == null) { // incompatible super type erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } } // eliminate non minimal super types if (remaining > 1) { nextType: for (int i = 0; i < superLength; i++) { TypeBinding erasedSuperType = erasedSuperTypes[i]; if (erasedSuperType == null) continue nextType; nextOtherType: for (int j = 0; j < superLength; j++) { if (i == j) continue nextOtherType; TypeBinding otherType = erasedSuperTypes[j]; if (otherType == null) continue nextOtherType; if (erasedSuperType instanceof ReferenceBinding) { if (otherType.id == TypeIds.T_JavaLangObject && erasedSuperType.isInterface()) continue nextOtherType; // keep Object for an interface if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } else if (erasedSuperType.isArrayType()) { if (otherType.isArrayType() // keep Object[...] for an interface array (same dimensions) && otherType.leafComponentType().id == TypeIds.T_JavaLangObject && otherType.dimensions() == erasedSuperType.dimensions() && erasedSuperType.leafComponentType().isInterface()) continue nextOtherType; if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } } } } return erasedSuperTypes; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java
License:Open Source License
/** * Check all parameters in methodSpec against the resolved role method. * Also record which parameters (including result) need translation (lifting/lowering). * * Pre: not called if parameter mappings are present. * @param methodSpec//from ww w .j a va2 s .co m */ protected boolean internalCheckParametersCompatibility(MethodSpec methodSpec, TypeBinding[] roleParams, TypeBinding[] baseParams) { if (baseParams.length < roleParams.length) { this.scope.problemReporter().tooFewArgumentsInMethodMapping(this.roleMethodSpec, methodSpec, false/*callout*/); this.binding.tagBits |= TagBits.HasMappingIncompatibility; return false; } else { // before modifying the parameters array copy it: System.arraycopy(this.roleMethodSpec.parameters, 0, this.roleMethodSpec.parameters = new TypeBinding[roleParams.length], 0, roleParams.length); for (int j = 0; j < roleParams.length; j++) { TypeBinding baseParam = baseParams[j]; TypeBinding roleParam = roleParams[j]; if (baseParam.dimensions() != roleParam.dimensions()) { this.scope.problemReporter().incompatibleMappedArgument(baseParam, roleParam, this.roleMethodSpec, j, /*callout*/false); this.binding.tagBits |= TagBits.HasMappingIncompatibility; continue; // no real type checking needed. } TypeBinding baseLeaf = baseParam.leafComponentType(); TypeBinding roleLeaf = roleParam.leafComponentType(); ASTNode location = (methodSpec.hasSignature) ? (ASTNode) methodSpec.arguments[j] : methodSpec; boolean compatibilityViaBaseAnchor = false; boolean hasReportedError = false; boolean isTypeVariable = false; try { // capture continue exits // unbound type variable matches everything: if (roleParam.isTypeVariable()) { TypeVariableBinding typeVariableBinding = (TypeVariableBinding) roleParam; if (typeVariableBinding.firstBound == null) continue; // use bound for type checking below, yet need not check two-way compatibility: isTypeVariable = true; roleLeaf = typeVariableBinding.firstBound.leafComponentType(); } int dimensions = roleParam.dimensions(); if (baseLeaf.isCompatibleWith(roleLeaf)) { this.roleMethodSpec.parameters[j] = roleParam; continue; } if (RoleTypeCreator.isCompatibleViaBaseAnchor(this.scope, baseLeaf, roleLeaf, TokenNameBINDIN)) { this.roleMethodSpec.parameters[j] = roleParam; compatibilityViaBaseAnchor = true; continue; } TypeBinding roleToLiftTo = null; if (isReplaceCallin()) { TypeBinding roleSideType = roleLeaf; if (roleSideType.isRole()) { ReferenceBinding roleRef = (ReferenceBinding) roleSideType; roleRef = (ReferenceBinding) TeamModel .strengthenRoleType(this.scope.enclosingReceiverType(), roleRef); if (TypeBinding.equalsEquals(roleRef.baseclass(), baseLeaf)) { if (dimensions > 0) { if (roleRef instanceof DependentTypeBinding) roleToLiftTo = ((DependentTypeBinding) roleRef).getArrayType(dimensions); else roleToLiftTo = this.scope.createArrayType(roleRef, dimensions); // FIXME(SH): is this OK? } else { roleToLiftTo = roleRef; } } } } else { // this uses OTJLD 2.3.3(a) adaptation which is not reversible, ie., not usable for replace: roleToLiftTo = TeamModel.getRoleToLiftTo(this.scope, baseParam, roleParam, false, location); } if (roleToLiftTo != null) { // success by translation methodSpec.argNeedsTranslation[j] = true; this.roleMethodSpec.argNeedsTranslation[j] = true; this.roleMethodSpec.parameters[j] = roleToLiftTo; // this applies to all bindings // still need to check for ambiguity/abstract role: ReferenceBinding enclosingTeam = this.scope.enclosingSourceType().enclosingType(); int iProblem = enclosingTeam.getTeamModel() .canLiftingFail((ReferenceBinding) roleToLiftTo.leafComponentType()); if (iProblem > 0) addRoleLiftingProblem((ReferenceBinding) roleToLiftTo.leafComponentType(), iProblem); continue; } // check auto(un)boxing: if (this.scope.isBoxingCompatibleWith(baseLeaf, roleLeaf)) continue; if (roleParam instanceof ReferenceBinding) { ReferenceBinding roleRef = (ReferenceBinding) roleParam; if (roleRef.isRole() && roleRef.baseclass() != null) { this.scope.problemReporter().typeMismatchErrorPotentialLift(location, baseParam, roleParam, roleRef.baseclass()); hasReportedError = true; continue; } } // no compatibility detected: this.scope.problemReporter().incompatibleMappedArgument(baseParam, roleParam, this.roleMethodSpec, j, /*callout*/false); hasReportedError = true; } finally { if (hasReportedError) this.binding.tagBits |= TagBits.HasMappingIncompatibility; // regardless of continue, check this last because it is the least precise message: if (!hasReportedError && baseLeaf.isCompatibleWith(roleLeaf)) { if (isReplaceCallin() && !isTypeVariable) { boolean twowayCompatible = compatibilityViaBaseAnchor ? RoleTypeCreator.isCompatibleViaBaseAnchor(this.scope, baseLeaf, roleLeaf, TokenNameBINDOUT) : roleLeaf.isCompatibleWith(baseLeaf); if (!twowayCompatible) { // requires two-way compatibility (see additional paragraph in 4.5(d)) this.scope.problemReporter().typesNotTwowayCompatibleInReplace(baseParam, roleParam, location, j); } } } } } } return true; // unused in the callin case }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java
License:Open Source License
/** Check whether the baseSpec has a result compatible via replace. */ public void checkResultForReplace(MethodSpec baseSpec) { boolean typeIdentityRequired = true; // default unless return is type variable // covariant return requires a fresh type parameter for the role's return type: if (baseSpec.covariantReturn && this.roleMethodSpec.returnType != null) { TypeBinding resolvedRoleReturn = this.roleMethodSpec.returnType.resolvedType; if (resolvedRoleReturn != null) { if (!resolvedRoleReturn.isTypeVariable()) { this.scope.problemReporter() .covariantReturnRequiresTypeParameter(this.roleMethodSpec.returnType); this.binding.tagBits |= TagBits.HasMappingIncompatibility; } else { // is the type parameter "fresh"? for (Argument arg : this.roleMethodSpec.arguments) { if (typeUsesTypeVariable(arg.type.resolvedType.leafComponentType(), resolvedRoleReturn)) { this.scope.problemReporter().duplicateUseOfTypeVariableInCallin( this.roleMethodSpec.returnType, resolvedRoleReturn); this.binding.tagBits |= TagBits.HasMappingIncompatibility; break; }// w w w.j a va2s . c o m } } } } TypeVariableBinding returnVariable = MethodModel .checkedGetReturnTypeVariable(this.roleMethodSpec.resolvedMethod); if (returnVariable != null) { // unbounded type variable always matches: if (returnVariable.firstBound == null) return; // in case of type variable only one-way compatibility is needed even for replace: typeIdentityRequired = false; } // now go for the actual type checking: TypeBinding baseReturn = baseSpec.resolvedMethod.returnType; TypeBinding roleReturn = MethodModel.getReturnType(this.roleMethodSpec.resolvedMethod); TypeBinding roleReturnLeaf = roleReturn != null ? roleReturn.leafComponentType() : null; if (roleReturnLeaf instanceof ReferenceBinding && ((ReferenceBinding) roleReturnLeaf).isRole()) { // strengthen: roleReturnLeaf = TeamModel.strengthenRoleType(this.scope.enclosingSourceType(), roleReturnLeaf); if (roleReturnLeaf == null) { // FIXME(SH): testcase and better handling String roleReturnName = roleReturn != null ? new String(roleReturn.readableName()) : "null return type"; //$NON-NLS-1$ throw new InternalCompilerError("role strengthening for " + roleReturnName + " -> null"); //$NON-NLS-1$ //$NON-NLS-2$ } // bound roles use their topmost bound super: if (((ReferenceBinding) roleReturnLeaf).baseclass() != null) roleReturnLeaf = RoleModel.getTopmostBoundRole(this.scope, (ReferenceBinding) roleReturnLeaf); // need the RTB: if (!(roleReturnLeaf instanceof DependentTypeBinding)) roleReturnLeaf = RoleTypeCreator.maybeWrapUnqualifiedRoleType(roleReturnLeaf, this.scope.enclosingSourceType()); // array? int dims = roleReturn != null ? roleReturn.dimensions() : 0; if (dims == 0) { roleReturn = roleReturnLeaf; this.realRoleReturn = roleReturnLeaf; } else { roleReturn = ((DependentTypeBinding) roleReturnLeaf).getArrayType(dims); this.realRoleReturn = ((DependentTypeBinding) roleReturnLeaf).getArrayType(dims); } } if (baseReturn == null || baseReturn == TypeBinding.VOID) { // OTJLD 4.4(b): "A callin method bound with replace // to a base method returning void // must not declare a non-void result." if (!(roleReturn == null || roleReturn == TypeBinding.VOID)) { this.scope.problemReporter().callinIllegalRoleReturnReturn(baseSpec, this.roleMethodSpec); this.binding.tagBits |= TagBits.HasMappingIncompatibility; } } else { if (roleReturn == null || roleReturn == TypeBinding.VOID) { this.baseMethodNeedingResultFromBasecall = baseSpec; // will be reported in checkBaseResult(). return; } TypeBinding baseLeaf = baseReturn.leafComponentType(); if (baseLeaf instanceof DependentTypeBinding) { // instantiate relative to Role._OT$base: ReferenceBinding enclosingRole = this.scope.enclosingSourceType(); FieldBinding baseField = enclosingRole.getField(IOTConstants._OT_BASE, true); if (baseField != null && baseField.isValidBinding()) baseReturn = baseField.getRoleTypeBinding((ReferenceBinding) baseLeaf, baseReturn.dimensions()); } // check auto(un)boxing: if (this.scope.isBoxingCompatibleWith(roleReturn, baseReturn)) return; Config oldConfig = Config.createOrResetConfig(this); try { if (!roleReturn.isCompatibleWith(baseReturn)) { if (typeIdentityRequired) { this.scope.problemReporter().callinIncompatibleReturnType(baseSpec, this.roleMethodSpec); this.binding.tagBits |= TagBits.HasMappingIncompatibility; return; } // else we still needed the lowering test } // callin replace requires two way compatibility: baseSpec.returnNeedsTranslation = Config.getLoweringRequired(); } finally { Config.removeOrRestore(oldConfig, this); } // from now on don't bother with arrays any more (dimensions have been checked): roleReturn = roleReturn.leafComponentType(); baseReturn = baseReturn.leafComponentType(); TypeBinding translatedReturn = baseSpec.returnNeedsTranslation ? ((ReferenceBinding) roleReturn).baseclass() : roleReturn; if (translatedReturn.isTypeVariable()) { TypeBinding firstBound = ((TypeVariableBinding) translatedReturn).firstBound; if (firstBound != null) translatedReturn = firstBound; } if (!baseReturn.isCompatibleWith(translatedReturn)) { this.scope.problemReporter().callinIncompatibleReturnTypeBaseCall(baseSpec, this.roleMethodSpec); this.binding.tagBits |= TagBits.HasMappingIncompatibility; } } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java
License:Open Source License
private boolean typeUsesTypeVariable(TypeBinding type, TypeBinding variable) { if (TypeBinding.equalsEquals(type.leafComponentType(), variable)) return true; for (TypeVariableBinding t : type.typeVariables()) if (typeUsesTypeVariable(t, variable)) return true; if (type.isTypeVariable()) { if (typeUsesTypeVariable(((ReferenceBinding) type).superclass(), variable)) return true; for (TypeBinding superIfc : ((ReferenceBinding) type).superInterfaces()) if (typeUsesTypeVariable(superIfc, variable)) return true; }/* w w w .ja v a2 s . co m*/ return false; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference.java
License:Open Source License
@Override public TypeBinding resolveType(BlockScope scope, boolean checkBounds) { TypeBinding baseType = this.resolvedType = this.baseReference.resolveType(scope); if (this.roleReference.getTypeName().length > 1) { scope.problemReporter().qualifiedLiftingType(this.roleReference, scope.enclosingSourceType()); return invalidate(baseType); }/* w w w.j a va 2 s.c om*/ TypeBinding roleType = this.roleReference.resolveType(scope); if (scope.kind != Scope.BLOCK_SCOPE) { // not a catch block? if (!TeamModel.isAnyTeam(scope.enclosingSourceType())) { scope.problemReporter().liftingTypeNotAllowedHere(scope.methodScope().referenceContext, this); return invalidate(roleType); } } if (baseType == null || baseType instanceof MissingTypeBinding) return invalidate(roleType); if (roleType == null || roleType instanceof MissingTypeBinding) return invalidate(baseType); if (roleType.isArrayType()) { baseType = baseType.leafComponentType(); roleType = roleType.leafComponentType(); } if (roleType.isBaseType()) { scope.problemReporter().primitiveTypeNotAllowedForLifting(scope.referenceType(), this.roleReference, roleType); return invalidate(roleType); } if (baseType.isBaseType()) { scope.problemReporter().primitiveTypeNotAllowedForLifting(scope.referenceType(), this.baseReference, baseType); return invalidate(roleType); } ReferenceBinding roleRefType = (ReferenceBinding) roleType; if (!roleRefType.isValidBinding()) // already reported. return invalidate(roleType); if (!roleRefType.isDirectRole()) { scope.problemReporter().needRoleInLiftingType(scope.referenceType(), this.roleReference, roleType); return invalidate(roleType); } if (roleRefType.isSynthInterface()) roleRefType = roleRefType.getRealClass(); if (roleRefType.roleModel.hasBaseclassProblem()) {// already reported for the role class. scope.referenceContext().tagAsHavingErrors(); // -> mark method as erroneous, too. return invalidate(roleType); } // TODO (SH): maybe look for bound sub-type? // Note (SH): calling baseclass() requires STATE_LENV_DONE_FIELDS_AND_METHODS: Dependencies.ensureBindingState(roleRefType, ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS); if (baseType.isTypeVariable() && ((TypeVariableBinding) baseType).roletype != null) { // resolving "<B base R> as R": roleRefType = ((TypeVariableBinding) baseType).roletype; // ambiguity is handled by _OT$lift_dynamic which may or may not declare LiftingFailedException } else if ((baseType.tagBits & TagBits.HierarchyHasProblems) != 0) { // already reported (?) } else { // static adjustment (OTJLD 2.3.2(a)): roleRefType = (ReferenceBinding) TeamModel.getRoleToLiftTo(scope, baseType, roleRefType, true, this); if (roleRefType == null) roleRefType = (ReferenceBinding) roleType; // revert unsuccessful adjustment if (roleRefType.baseclass() == null || RoleModel.hasTagBit(roleRefType, RoleModel.BaseclassHasProblems)) { scope.problemReporter().roleNotBoundCantLift(scope.referenceType(), this.roleReference, roleType); return invalidate(roleType); } if (baseType.isRole()) // see http://trac.objectteams.org/ot/ticket/73 baseType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(baseType, scope.enclosingReceiverType()); if (baseType == null) return invalidate(roleType); Config oldConfig = Config.createOrResetConfig(this); try { // fetch role's base class and perform substitutions: ReferenceBinding roleBase = roleRefType.baseclass(); if (roleType.isParameterizedType()) { ParameterizedTypeBinding parameterizedRole = (ParameterizedTypeBinding) roleType; TypeBinding[] typeArgs = parameterizedRole.arguments; ITeamAnchor anchor = null; if (roleRefType.baseclass() instanceof RoleTypeBinding) anchor = ((RoleTypeBinding) roleRefType.baseclass())._teamAnchor; roleBase = parameterizedRole.environment.createParameterizedType( (ReferenceBinding) roleBase.original(), typeArgs, anchor, -1, roleBase.enclosingType(), roleBase.getTypeAnnotations()); } // THE compatibility check: if (!baseType.isCompatibleWith(roleBase) || Config.getLoweringRequired()) { scope.problemReporter().incompatibleBaseForRole(scope.referenceType(), this, roleType, baseType); return invalidate(roleType); } } finally { Config.removeOrRestore(oldConfig, this); } } return this.resolvedType; }