/** * This method is responsible for performing type inference on closure argument types whenever code like this is * found: <code>foo.collect { it.toUpperCase() }</code>. * In this case, the type checker tries to find if the <code>collect</code> method has its {@link Closure} argument * annotated with {@link groovy.transform.stc.ClosureParams}. If yes, then additional type inference can be performed * and the type of <code>it</code> may be inferred. * * @param receiver * @param arguments * @param expression a closure expression for which the argument types should be inferred * @param param the parameter where to look for a {@link groovy.transform.stc.ClosureParams} annotation. * @param selectedMethod the method accepting a closure */ protected void inferClosureParameterTypes(final ClassNode receiver, final Expression arguments, final ClosureExpression expression, final Parameter param, final MethodNode selectedMethod) { List<AnnotationNode> annotations = param.getAnnotations(CLOSUREPARAMS_CLASSNODE); if (annotations != null && !annotations.isEmpty()) { for (AnnotationNode annotation : annotations) { Expression hintClass = annotation.getMember("value"); Expression options = annotation.getMember("options"); Expression resolverClass = annotation.getMember("conflictResolutionStrategy"); if (hintClass instanceof ClassExpression) { doInferClosureParameterTypes(receiver, arguments, expression, selectedMethod, hintClass, resolverClass, options); } } } else if (isSAMType(param.getOriginType())) { // SAM coercion inferSAMType(param, receiver, selectedMethod, InvocationWriter.makeArgumentList(arguments), expression); } }
if (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)) { return true;
GenericsType gt = GenericsUtils.buildWildcardType(parameterType); if (!gt.isCompatibleWith(argumentType)) { boolean samCoercion = isSAMType(parameterType) && argumentType.equals(CLOSURE_TYPE); if (!samCoercion) return false;
if (rightRedirect.isDerivedFrom(CLOSURE_TYPE) && isSAMType(leftRedirect) && rightExpression instanceof ClosureExpression) { return inferSAMTypeGenericsInAssignment(left, findSAM(left), right, (ClosureExpression) rightExpression);