| 1153 | } |
| 1154 | |
| 1155 | const CallableSignature* ExpressionFuzzer::chooseRandomConcreteSignature( |
| 1156 | const TypePtr& returnType, |
| 1157 | const std::string& functionName) { |
| 1158 | if (expressionToSignature_.find(functionName) == |
| 1159 | expressionToSignature_.end()) { |
| 1160 | return nullptr; |
| 1161 | } |
| 1162 | auto baseType = typeToBaseName(returnType); |
| 1163 | auto itr = expressionToSignature_[functionName].find(baseType); |
| 1164 | if (itr == expressionToSignature_[functionName].end()) { |
| 1165 | return nullptr; |
| 1166 | } |
| 1167 | // Only function signatures whose return type equals to returnType are |
| 1168 | // eligible. There may be ineligible signatures in signaturesMap_ because |
| 1169 | // the map keys only differentiate top-level type kinds. |
| 1170 | std::vector<const CallableSignature*> eligible; |
| 1171 | for (auto signature : itr->second) { |
| 1172 | if (signature->returnType->equivalent(*returnType)) { |
| 1173 | eligible.push_back(signature); |
| 1174 | } |
| 1175 | } |
| 1176 | if (eligible.empty()) { |
| 1177 | return nullptr; |
| 1178 | } |
| 1179 | |
| 1180 | // Randomly pick a function that can return `returnType`. |
| 1181 | size_t idx = rand32(0, eligible.size() - 1); |
| 1182 | return eligible[idx]; |
| 1183 | } |
| 1184 | |
| 1185 | const CallableSignature* ExpressionFuzzer::findConcreteSignature( |
| 1186 | const std::vector<TypePtr>& argTypes, |
nothing calls this directly
no test coverage detected