//Попытка вычислить типы после подстановки типов формальных параметров public static bool TryToDeduceTypesInLambda(function_lambda_definition lambda_syntax_node, delegate_internal_interface formal_delegate, type_node[] deduced, List<int> nils, out Exception exception_on_body_compilation) { var there_are_undeduced_params = false; var param_counter = 0; var visitor = SystemLibrary.SystemLibrary.syn_visitor; var result = true; exception_on_body_compilation = null; if (lambda_syntax_node.formal_parameters == null || lambda_syntax_node.formal_parameters.params_list == null || lambda_syntax_node.formal_parameters.params_list.Count == 0) { return false; } foreach (var t in lambda_syntax_node.formal_parameters.params_list) { var lambdaInfType = t.vars_type as lambda_inferred_type; if (lambdaInfType != null && lambdaInfType.real_type is lambda_any_type_node) { if (!CheckIfTypeDependsOnUndeducedGenericParameters(formal_delegate.parameters[param_counter].type, deduced)) //Если тип параметра не зависит от невыведенных дженерик-параметров, то можем вычислить этот тип явно { lambdaInfType.real_type = generic_convertions.determine_type(formal_delegate.parameters[param_counter].type, deduced.ToList(), true); //инстанцируем и записываем вычесленный тип } else { there_are_undeduced_params = true; //иначе мы не сможем вывести тип возвращаемого значения break; } } param_counter += t.idents.idents.Count; } if (!there_are_undeduced_params && lambda_syntax_node.return_type is lambda_inferred_type && ((lambda_inferred_type)lambda_syntax_node.return_type).real_type is lambda_any_type_node) { var lambdaName = lambda_syntax_node.lambda_name; var fl = lambda_syntax_node.lambda_visit_mode; lambda_syntax_node.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; var aux_name = LambdaHelper.GetAuxiliaryLambdaName(lambda_syntax_node.lambda_name); lambda_syntax_node.lambda_name = aux_name; try { visitor.visit(lambda_syntax_node); //пробуем скомпилировать тело лямбды, вычислим тип возвращаемого значения } catch (Exception exc) { exception_on_body_compilation = exc; // Если произошло исключение то запишем его в выходной параметр, оно потом будет обработано вызывающим методом result = false; } finally { var context = visitor.context; //Далее надо удалить ненужный узел из списка функций LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, lambda_syntax_node); lambda_syntax_node.lambda_name = lambdaName; lambda_syntax_node.lambda_visit_mode = fl; if (result) { if (!DeduceInstanceTypes(formal_delegate.return_value_type, (type_node)((lambda_inferred_type)lambda_syntax_node.return_type).real_type, deduced, nils)) //Выводим дженерик-параметры после того как вычислили тип возвращаемого значения { result = false; } } } } return result; }