| 1007 | } |
| 1008 | |
| 1009 | ConstantValue eval(EvalContext& context, const Args& args, SourceRange, |
| 1010 | const CallExpression::SystemCallInfo& callInfo) const final { |
| 1011 | ConstantValue arr = args[0]->eval(context); |
| 1012 | if (!arr) |
| 1013 | return nullptr; |
| 1014 | |
| 1015 | auto [iterExpr, iterVar] = callInfo.getIteratorInfo(); |
| 1016 | auto guard = context.disableCaching(); |
| 1017 | auto iterVal = context.createLocal(iterVar); |
| 1018 | |
| 1019 | if (arr.isMap()) { |
| 1020 | AssociativeArray results; |
| 1021 | for (auto& [key, val] : *arr.map()) { |
| 1022 | *iterVal = val; |
| 1023 | ConstantValue cv = iterExpr->eval(context); |
| 1024 | if (!cv) |
| 1025 | return nullptr; |
| 1026 | |
| 1027 | results.emplace(key, std::move(cv)); |
| 1028 | } |
| 1029 | return results; |
| 1030 | } |
| 1031 | else { |
| 1032 | auto doMap = [&, ie = iterExpr](auto& container, auto& results) { |
| 1033 | for (auto& elem : container) { |
| 1034 | *iterVal = elem; |
| 1035 | ConstantValue cv = ie->eval(context); |
| 1036 | if (!cv) |
| 1037 | return false; |
| 1038 | |
| 1039 | results.emplace_back(std::move(cv)); |
| 1040 | } |
| 1041 | return true; |
| 1042 | }; |
| 1043 | |
| 1044 | if (arr.isQueue()) { |
| 1045 | SVQueue results; |
| 1046 | if (!doMap(*arr.queue(), results)) |
| 1047 | return nullptr; |
| 1048 | return results; |
| 1049 | } |
| 1050 | else { |
| 1051 | ConstantValue::Elements results; |
| 1052 | if (!doMap(std::get<ConstantValue::Elements>(arr.getVariant()), results)) |
| 1053 | return nullptr; |
| 1054 | return results; |
| 1055 | } |
| 1056 | } |
| 1057 | } |
| 1058 | }; |
| 1059 | |
| 1060 | void Builtins::registerArrayMethods() { |
nothing calls this directly
no test coverage detected