| 2101 | } |
| 2102 | |
| 2103 | static value |
| 2104 | json_subscript (const value& val, value* val_data, |
| 2105 | value&& sub, |
| 2106 | const location& sloc, |
| 2107 | const location& bloc) |
| 2108 | { |
| 2109 | const json_value* jv (val.null ? nullptr : &val.as<json_value> ()); |
| 2110 | |
| 2111 | // For consistency with other places treat JSON null value as maybe |
| 2112 | // missing array/object. In particular, we don't want to fail trying to |
| 2113 | // lookup by-name on a null value which could have been an object. |
| 2114 | // |
| 2115 | if (jv != nullptr && jv->type == json_type::null) |
| 2116 | jv = nullptr; |
| 2117 | |
| 2118 | // Process subscript even if the value is null to make sure it is valid. |
| 2119 | // |
| 2120 | bool index; |
| 2121 | uint64_t i (0); |
| 2122 | string n; |
| 2123 | |
| 2124 | // Always interpret uint64-typed subscript as index even for objects. |
| 2125 | // This can be used to, for example, to iterate with an index over object |
| 2126 | // members. |
| 2127 | // |
| 2128 | if (!sub.null && sub.type == &value_traits<uint64_t>::value_type) |
| 2129 | { |
| 2130 | i = sub.as<uint64_t> (); |
| 2131 | index = true; |
| 2132 | } |
| 2133 | else |
| 2134 | { |
| 2135 | // How we interpret the subscript depends on the JSON value type. For |
| 2136 | // objects we treat it as a string (member name) and for everything else |
| 2137 | // as an index. |
| 2138 | // |
| 2139 | // What if the value is null and we don't have a JSON type? In this case |
| 2140 | // we treat as a string since a valid number is also a valid string. |
| 2141 | // |
| 2142 | try |
| 2143 | { |
| 2144 | if (jv == nullptr || jv->type == json_type::object) |
| 2145 | { |
| 2146 | n = convert<string> (move (sub)); |
| 2147 | index = false; |
| 2148 | } |
| 2149 | else |
| 2150 | { |
| 2151 | i = convert<uint64_t> (move (sub)); |
| 2152 | index = true; |
| 2153 | } |
| 2154 | } |
| 2155 | catch (const invalid_argument& e) |
| 2156 | { |
| 2157 | // We will likely be trying to interpret a member name as an integer |
| 2158 | // due to the incorrect value type so issue appropriate diagnostics. |
| 2159 | // |
| 2160 | diag_record dr (fail (sloc)); |
nothing calls this directly
no test coverage detected