| 200 | } |
| 201 | |
| 202 | Value NoOverloadResult(absl::string_view name, |
| 203 | absl::Span<const cel::Value> args, bool receiver_style, |
| 204 | ExecutionFrameBase& frame) { |
| 205 | // No matching overloads. |
| 206 | // Such absence can be caused by presence of CelError in arguments. |
| 207 | // To enable behavior of functions that accept CelError( &&, || ), CelErrors |
| 208 | // should be propagated along execution path. |
| 209 | for (size_t i = 0; i < args.size(); i++) { |
| 210 | const auto& arg = args[i]; |
| 211 | if (cel::InstanceOf<cel::ErrorValue>(arg)) { |
| 212 | return arg; |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | if (frame.unknown_processing_enabled()) { |
| 217 | // Already converted partial unknowns to unknown sets so just merge. |
| 218 | absl::optional<UnknownValue> unknown_set = |
| 219 | frame.attribute_utility().MergeUnknowns(args); |
| 220 | if (unknown_set.has_value()) { |
| 221 | return *unknown_set; |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | // If no errors or unknowns in input args, create new CelError for missing |
| 226 | // overload. |
| 227 | std::string signature; |
| 228 | if (receiver_style) { |
| 229 | if (args.empty()) { |
| 230 | // Should not be possible, but return a sensible error in case of logic |
| 231 | // error. |
| 232 | return ErrorValue( |
| 233 | CreateNoMatchingOverloadError(absl::StrCat("().", name, "()"))); |
| 234 | } |
| 235 | return ErrorValue(CreateNoMatchingOverloadError(absl::StrCat( |
| 236 | "(", |
| 237 | ToLegacyKindName(cel::KindToString(ValueKindToKind(args[0].kind()))), |
| 238 | ").", name, CallArgTypeString(args.subspan(1))))); |
| 239 | } |
| 240 | return cel::ErrorValue(CreateNoMatchingOverloadError( |
| 241 | absl::StrCat(name, CallArgTypeString(args)))); |
| 242 | } |
| 243 | |
| 244 | absl::StatusOr<Value> AbstractFunctionStep::DoEvaluate( |
| 245 | ExecutionFrame* frame) const { |
no test coverage detected