[JSON] Add error reporting to fromJSON and ObjectMapper
authorSam McCall <sam.mccall@gmail.com>
Wed, 23 Sep 2020 23:14:12 +0000 (01:14 +0200)
committerSam McCall <sam.mccall@gmail.com>
Wed, 23 Sep 2020 23:20:09 +0000 (01:20 +0200)
commitfa69b608063eecba76fb35d167b063cbfe532c28
tree98cb01a21781c781ad94350ab3ac9e9b086336cf
parent881aba7071c6e4cc2417e875ca5027ec7c0a92a3
[JSON] Add error reporting to fromJSON and ObjectMapper

Translating between JSON objects and C++ strutctures is common.
From experience in clangd, fromJSON/ObjectMapper work well and save a lot of
code, but aren't adopted elsewhere at least partly due to total lack of error
reporting beyond "ok"/"bad".

The recently-added error model should be rich enough for most applications.
It requires tracking the path within the root object and reporting local
errors at appropriate places.
To do this, we exploit the fact that the call graph of recursive
parse functions mirror the structure of the JSON itself.
The current path is represented as a linked list of segments, each of which is
on the stack as a parameter. Concretely, fromJSON now looks like:
  bool fromJSON(const Value&, T&, Path);

Beyond the signature change, this is reasonably unobtrusive: building
the path segments is mostly handled by ObjectMapper and the vector<T> fromJSON.
However the root caller of fromJSON must now create a Root object to
store the errors, which is a little clunky.

I've added high-level parse<T>(StringRef) -> Expected<T>, but it's not
general enough to be the primary interface I think (at least, not usable in
clangd).

All existing users (mostly just clangd) are updated in this patch,
making this change backwards-compatible is a bit hairy.

Differential Revision: https://reviews.llvm.org/D88103
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdLSPServer.h
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp
clang-tools-extra/clangd/index/Index.cpp
clang-tools-extra/clangd/index/Index.h
lldb/source/Utility/StructuredData.cpp
llvm/include/llvm/Support/JSON.h
llvm/lib/Analysis/TFUtils.cpp
llvm/unittests/Support/JSONTest.cpp