/** * If 'hasSignature' check the return type of the bound method against the declared return type. */ public boolean checkRoleReturnType(CallinCalloutScope scope, boolean isCallout) { TypeBinding methodReturn = boundMethodReturnType(); TypeBinding resolvedReturnType = this.returnType.resolvedType; TypeBinding firstBound = null; if (resolvedReturnType.isTypeVariable()) { firstBound = ((TypeVariableBinding) resolvedReturnType).firstBound; // if declared return type is a type variable, so must the return type of the resolved method: if (!isMethodReturnTypeVariable(this.resolvedMethod)) { scope.problemReporter().differentReturnInMethodSpec(this, /*isCallout*/ false); return false; } } // the role side of a callout may indeed refine the return type // of its inherited role method: if (isCallout) if (this.returnType.resolvedType.isCompatibleWith(methodReturn)) return true; // in other cases types have to be identical: if (!MethodModel.hasUnboundedReturnType( this.resolvedMethod) // unbounded type variable always matches && !TypeAnalyzer.isSameType(scope.enclosingSourceType(), resolvedReturnType, methodReturn) && !TypeAnalyzer.isSameType(scope.enclosingSourceType(), firstBound, methodReturn)) { scope .problemReporter() .differentReturnInMethodSpec( this, ((AbstractMethodMappingDeclaration) scope.referenceContext).isCallout()); return false; } return true; }
/** * If 'hasSignature' check the return type of the bound method against the declared return type. */ public boolean checkBaseReturnType(CallinCalloutScope scope, int bindDir) { TypeBinding methodReturn = boundMethodReturnType(); if (!TypeAnalyzer.isSameType( scope.enclosingSourceType(), this.returnType.resolvedType, methodReturn)) { if (RoleTypeCreator.isCompatibleViaBaseAnchor( scope, methodReturn, this.returnType.resolvedType, bindDir)) return true; if ((methodReturn.tagBits & TagBits.HasMissingType) == 0) scope .problemReporter() .differentReturnInMethodSpec( this, ((AbstractMethodMappingDeclaration) scope.referenceContext).isCallout()); return false; } return true; }
/** * If 'hasSignature' check the parameter types of the bound method against the declared parameter * types. */ public boolean checkParameterTypes(CallinCalloutScope scope, boolean isBase) { // retrieve (un-enhanced) parameters from the actual resolved method: TypeBinding[] realParameters = this.resolvedMethod.getSourceParameters(); for (int i = 0; i < realParameters.length; i++) { TypeReference specifiedArgType = this.arguments[i].type; TypeBinding realParameter = realParameters[i]; if (!realParameter.isValidBinding() || specifiedArgType.resolvedType == null) continue; ReferenceBinding baseclass = scope.enclosingReceiverType().baseclass(); if (isBase && baseclass != null && baseclass.isTeam() && realParameter.isRole()) realParameter = TeamModel.strengthenRoleType(baseclass, realParameter); if (!TypeAnalyzer.isSameType( scope.enclosingSourceType(), specifiedArgType.resolvedType, realParameter)) { scope .problemReporter() .differentParamInMethodSpec( this, specifiedArgType, realParameter, ((AbstractMethodMappingDeclaration) scope.referenceContext).isCallout()); return false; } } return true; }