| 914 | } |
| 915 | |
| 916 | core::TypedExprPtr ExpressionFuzzer::generateArgFunction(const TypePtr& arg) { |
| 917 | const auto& functionType = arg->asFunction(); |
| 918 | |
| 919 | std::vector<TypePtr> args; |
| 920 | std::vector<std::string> names; |
| 921 | std::vector<core::TypedExprPtr> inputs; |
| 922 | args.reserve(arg->size() - 1); |
| 923 | names.reserve(arg->size() - 1); |
| 924 | inputs.reserve(arg->size() - 1); |
| 925 | |
| 926 | for (auto i = 0; i < arg->size() - 1; ++i) { |
| 927 | args.push_back(arg->childAt(i)); |
| 928 | names.push_back(fmt::format("__a{}", i)); |
| 929 | inputs.push_back(std::make_shared<core::FieldAccessTypedExpr>( |
| 930 | args.back(), names.back())); |
| 931 | } |
| 932 | |
| 933 | const auto& returnType = functionType.children().back(); |
| 934 | |
| 935 | const auto baseType = typeToBaseName(returnType); |
| 936 | const auto& baseList = typeToExpressionList_[baseType]; |
| 937 | const auto& templateList = typeToExpressionList_[kTypeParameterName]; |
| 938 | |
| 939 | std::vector<std::string> eligible; |
| 940 | for (const auto& functionName : baseList) { |
| 941 | if (auto* signature = |
| 942 | findConcreteSignature(args, returnType, functionName)) { |
| 943 | eligible.push_back(functionName); |
| 944 | } else if ( |
| 945 | auto* signatureTemplate = |
| 946 | findSignatureTemplate(args, returnType, baseType, functionName)) { |
| 947 | eligible.push_back(functionName); |
| 948 | } |
| 949 | } |
| 950 | |
| 951 | for (const auto& functionName : templateList) { |
| 952 | if (auto* signatureTemplate = |
| 953 | findSignatureTemplate(args, returnType, baseType, functionName)) { |
| 954 | eligible.push_back(functionName); |
| 955 | } |
| 956 | } |
| 957 | |
| 958 | if (eligible.empty()) { |
| 959 | return std::make_shared<core::LambdaTypedExpr>( |
| 960 | ROW(std::move(names), std::move(args)), |
| 961 | generateArgConstant(returnType)); |
| 962 | } |
| 963 | |
| 964 | const auto idx = rand32(0, eligible.size() - 1); |
| 965 | const auto name = eligible[idx]; |
| 966 | |
| 967 | return std::make_shared<core::LambdaTypedExpr>( |
| 968 | ROW(std::move(names), std::move(args)), |
| 969 | std::make_shared<core::CallTypedExpr>(returnType, inputs, name)); |
| 970 | } |
| 971 | |
| 972 | core::TypedExprPtr ExpressionFuzzer::generateArg( |
| 973 | const TypePtr& arg, |