PsiType (GrClosableBlock closure) { List<PsiType> expectedReturnTypes = new ArrayList<>(); PsiElement parent = closure.getParent(); if (parent instanceof GrArgumentList && parent.getParent() instanceof GrMethodCall || parent instanceof GrMethodCall) { GrMethodCall call = (GrMethodCall)(parent instanceof GrArgumentList ? parent.getParent() : parent); GroovyResolveResult[] variants = call.getCallVariants(null); for (GroovyResolveResult variant : variants) { Map<GrExpression,Pair<PsiParameter,PsiType>> map = GrClosureSignatureUtil.mapArgumentsToParameters(variant, closure, true, true, call.getNamedArguments(), call.getExpressionArguments(), call.getClosureArguments()); if (map != null) { Pair<PsiParameter, PsiType> pair = map.get(closure); if (pair == null) continue; PsiParameter parameter = pair.getFirst(); PsiType type = parameter.getType(); if (TypesUtil.isPsiClassTypeToClosure(type)) { PsiType[] parameters = ((PsiClassType)type).getParameters(); if (parameters.length == 1) { expectedReturnTypes.add(parameters[0]); } } } } } else { for (PsiType expectedType : GroovyExpectedTypesProvider.getDefaultExpectedTypes(closure)) { if (TypesUtil.isPsiClassTypeToClosure(expectedType)) { PsiType[] parameters = ((PsiClassType)expectedType).getParameters(); if (parameters.length == 1) { expectedReturnTypes.add(parameters[0]); } } } } for (PsiType type : expectedReturnTypes) { if (PsiTypes.voidType().equals(type) || PsiTypes.voidType().equals(PsiPrimitiveType.getUnboxedType(type))) return PsiTypes.voidType(); } return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager()); }