From 57b468820fa68f609dedcb53abf8179208a5cec0 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 1 Oct 2019 17:41:52 +0000 Subject: [PATCH] [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 --- lldb/include/lldb/Utility/StructuredData.h | 1 - lldb/source/Utility/StructuredData.cpp | 148 ++++++++++------------------- 2 files changed, 48 insertions(+), 101 deletions(-) diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h index d2e21f42..01b14fc 100644 --- a/lldb/include/lldb/Utility/StructuredData.h +++ b/lldb/include/lldb/Utility/StructuredData.h @@ -548,7 +548,6 @@ public: }; static ObjectSP ParseJSON(std::string json_text); - static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); }; diff --git a/lldb/source/Utility/StructuredData.cpp b/lldb/source/Utility/StructuredData.cpp index b461070..783a080 100644 --- a/lldb/source/Utility/StructuredData.cpp +++ b/lldb/source/Utility/StructuredData.cpp @@ -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 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 - auto dict_up = std::make_unique(); +static StructuredData::ObjectSP ParseJSONValue(json::Value &value) { + if (json::Object *O = value.getAsObject()) + return ParseJSONObject(O); - 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; - } - } - return StructuredData::ObjectSP(); -} + if (json::Array *A = value.getAsArray()) + return ParseJSONArray(A); -static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) { - // The "JSONParser::Token::ObjectStart" token should have already been - // consumed by the time this function is called - auto array_up = std::make_unique(); + std::string s; + if (json::fromJSON(value, s)) + return std::make_shared(s); + + bool b; + if (json::fromJSON(value, b)) + return std::make_shared(b); + + int64_t i; + if (json::fromJSON(value, i)) + return std::make_shared(i); + + double d; + if (json::fromJSON(value, d)) + return std::make_shared(d); - std::string value; - std::string key; - while (true) { - StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser); - if (value_sp) - 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(uval); - } break; - - case JSONParser::Token::Float: { - double val; - if (llvm::to_float(value, val)) - return std::make_shared(val); - } break; - - case JSONParser::Token::String: - return std::make_shared(value); - - case JSONParser::Token::True: - case JSONParser::Token::False: - return std::make_shared(token == - JSONParser::Token::True); - - case JSONParser::Token::Null: - return std::make_shared(); - - default: - break; +static StructuredData::ObjectSP ParseJSONObject(json::Object *object) { + auto dict_up = std::make_unique(); + 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; } -StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) { - JSONParser json_parser(json_text); - StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser); - return object_sp; +static StructuredData::ObjectSP ParseJSONArray(json::Array *array) { + auto array_up = std::make_unique(); + for (json::Value &value : *array) { + if (StructuredData::ObjectSP value_sp = ParseJSONValue(value)) + array_up->AddItem(value_sp); + } + return array_up; } StructuredData::ObjectSP -- 2.7.4