[JSON] Use LLVM's library for decoding JSON in StructuredData

This patch replaces the hand-rolled JSON decoding in StructuredData with
LLVM's JSON library.

Differential revision: https://reviews.llvm.org/D68282

llvm-svn: 373360
This commit is contained in:
Jonas Devlieghere 2019-10-01 17:41:52 +00:00
parent 2783d81791
commit 57b468820f
2 changed files with 50 additions and 103 deletions

View File

@ -548,7 +548,6 @@ public:
};
static ObjectSP ParseJSON(std::string json_text);
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
};

View File

@ -9,7 +9,6 @@
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/STLExtras.h"
@ -22,10 +21,18 @@
using namespace lldb_private;
using namespace llvm;
// Functions that use a JSONParser to parse JSON into StructuredData
static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser);
static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser);
static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser);
static StructuredData::ObjectSP ParseJSONValue(json::Value &value);
static StructuredData::ObjectSP ParseJSONObject(json::Object *object);
static StructuredData::ObjectSP ParseJSONArray(json::Array *array);
StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
llvm::Expected<json::Value> value = json::parse(json_text);
if (!value) {
llvm::consumeError(value.takeError());
return nullptr;
}
return ParseJSONValue(*value);
}
StructuredData::ObjectSP
StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
@ -38,112 +45,53 @@ StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
buffer_or_error.getError().message());
return return_sp;
}
JSONParser json_parser(buffer_or_error.get()->getBuffer());
return_sp = ParseJSONValue(json_parser);
return return_sp;
return ParseJSON(buffer_or_error.get()->getBuffer().str());
}
static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) {
// The "JSONParser::Token::ObjectStart" token should have already been
// consumed by the time this function is called
static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
if (json::Object *O = value.getAsObject())
return ParseJSONObject(O);
if (json::Array *A = value.getAsArray())
return ParseJSONArray(A);
std::string s;
if (json::fromJSON(value, s))
return std::make_shared<StructuredData::String>(s);
bool b;
if (json::fromJSON(value, b))
return std::make_shared<StructuredData::Boolean>(b);
int64_t i;
if (json::fromJSON(value, i))
return std::make_shared<StructuredData::Integer>(i);
double d;
if (json::fromJSON(value, d))
return std::make_shared<StructuredData::Float>(d);
return StructuredData::ObjectSP();
}
static StructuredData::ObjectSP ParseJSONObject(json::Object *object) {
auto dict_up = std::make_unique<StructuredData::Dictionary>();
std::string value;
std::string key;
while (true) {
JSONParser::Token token = json_parser.GetToken(value);
if (token == JSONParser::Token::String) {
key.swap(value);
token = json_parser.GetToken(value);
if (token == JSONParser::Token::Colon) {
StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
if (value_sp)
dict_up->AddItem(key, value_sp);
else
break;
}
} else if (token == JSONParser::Token::ObjectEnd) {
return StructuredData::ObjectSP(dict_up.release());
} else if (token == JSONParser::Token::Comma) {
continue;
} else {
break;
}
for (auto &KV : *object) {
StringRef key = KV.first;
json::Value value = KV.second;
if (StructuredData::ObjectSP value_sp = ParseJSONValue(value))
dict_up->AddItem(key, value_sp);
}
return StructuredData::ObjectSP();
return dict_up;
}
static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) {
// The "JSONParser::Token::ObjectStart" token should have already been
// consumed by the time this function is called
static StructuredData::ObjectSP ParseJSONArray(json::Array *array) {
auto array_up = std::make_unique<StructuredData::Array>();
std::string value;
std::string key;
while (true) {
StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
if (value_sp)
for (json::Value &value : *array) {
if (StructuredData::ObjectSP value_sp = ParseJSONValue(value))
array_up->AddItem(value_sp);
else
break;
JSONParser::Token token = json_parser.GetToken(value);
if (token == JSONParser::Token::Comma) {
continue;
} else if (token == JSONParser::Token::ArrayEnd) {
return StructuredData::ObjectSP(array_up.release());
} else {
break;
}
}
return StructuredData::ObjectSP();
}
static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) {
std::string value;
const JSONParser::Token token = json_parser.GetToken(value);
switch (token) {
case JSONParser::Token::ObjectStart:
return ParseJSONObject(json_parser);
case JSONParser::Token::ArrayStart:
return ParseJSONArray(json_parser);
case JSONParser::Token::Integer: {
uint64_t uval;
if (llvm::to_integer(value, uval, 0))
return std::make_shared<StructuredData::Integer>(uval);
} break;
case JSONParser::Token::Float: {
double val;
if (llvm::to_float(value, val))
return std::make_shared<StructuredData::Float>(val);
} break;
case JSONParser::Token::String:
return std::make_shared<StructuredData::String>(value);
case JSONParser::Token::True:
case JSONParser::Token::False:
return std::make_shared<StructuredData::Boolean>(token ==
JSONParser::Token::True);
case JSONParser::Token::Null:
return std::make_shared<StructuredData::Null>();
default:
break;
}
return StructuredData::ObjectSP();
}
StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
JSONParser json_parser(json_text);
StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
return object_sp;
return array_up;
}
StructuredData::ObjectSP