diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h index f96e169f236e..dfd8ec0e180c 100644 --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -109,6 +109,35 @@ public: /// Return the generic pointer if this data structure is a generic type. lldb::SBScriptObject GetGenericValue() const; + /// Set the value corresponding to a key. If this data structure + /// is not a dictionary type, reset the type to be dictionary and overwrite + /// the previous data. + void SetValueForKey(const char *key, SBStructuredData &value); + + /// Change the type to unsigned interger and overwrite the previous data with + /// the new value. + void SetUnsignedIntegerValue(uint64_t value); + + /// Change the type to signed interger and overwrite the previous data with + /// the new value. + void SetSignedIntegerValue(int64_t value); + + /// Change the type to float and overwrite the previous data with the new + /// value. + void SetFloatValue(double value); + + /// Change the type to boolean and overwrite the previous data with the new + /// value. + void SetBooleanValue(bool value); + + /// Change the type to string and overwrite the previous data with the new + /// value. + void SetStringValue(const char *value); + + /// Change the type to generic and overwrite the previous data with the new + /// value. + void SetGenericValue(SBScriptObject value); + protected: friend class SBAttachInfo; friend class SBCommandReturnObject; diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h index fd0a7b94d3a6..b88962bc774d 100644 --- a/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/lldb/include/lldb/Core/StructuredDataImpl.h @@ -81,6 +81,41 @@ public: void SetObjectSP(const StructuredData::ObjectSP &obj) { m_data_sp = obj; } + void SetValueForKey(llvm::StringRef key, + const StructuredData::ObjectSP &value) { + if (!m_data_sp || + m_data_sp->GetType() != lldb::eStructuredDataTypeDictionary) { + m_data_sp = StructuredData::FromKeyValue(key, value); + } else if (StructuredData::Dictionary *dict = + m_data_sp->GetAsDictionary()) { + dict->AddItem(key, value); + } + } + + void SetUnsignedIntegerValue(uint64_t value) { + m_data_sp = StructuredData::FromInteger(value); + } + + void SetSignedIntegerValue(int64_t value) { + m_data_sp = StructuredData::FromInteger(value); + } + + void SetFloatValue(double value) { + m_data_sp = StructuredData::FromFloat(value); + } + + void SetBooleanValue(bool value) { + m_data_sp = StructuredData::FromBoolean(value); + } + + void SetStringValue(std::string value) { + m_data_sp = StructuredData::FromString(std::move(value)); + } + + void SetGenericValue(void *value) { + m_data_sp = StructuredData::FromGeneric(value); + } + lldb::StructuredDataType GetType() const { return (m_data_sp ? m_data_sp->GetType() : lldb::eStructuredDataTypeInvalid); diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h index 5e63ef92fac3..59a2fd60b398 100644 --- a/lldb/include/lldb/Utility/StructuredData.h +++ b/lldb/include/lldb/Utility/StructuredData.h @@ -432,7 +432,7 @@ public: } return success; } - + template bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const { ObjectSP value_sp = GetValueForKey(key); @@ -574,6 +574,30 @@ public: void *m_object; }; + template static ObjectSP FromInteger(T value) { + return std::make_shared>(value); + } + + static StructuredData::ObjectSP FromFloat(double value) { + return std::make_shared(value); + } + static StructuredData::ObjectSP FromBoolean(bool value) { + return std::make_shared(value); + } + static StructuredData::ObjectSP FromString(std::string value) { + return std::make_shared(value); + } + static StructuredData::ObjectSP FromGeneric(void *value) { + return std::make_shared(value); + } + + static StructuredData::ObjectSP + FromKeyValue(llvm::StringRef key, const StructuredData::ObjectSP &value_sp) { + auto dict_sp = std::make_shared(); + dict_sp->AddItem(key, value_sp); + return dict_sp; + } + static ObjectSP ParseJSON(llvm::StringRef json_text); static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); static bool IsRecordType(const ObjectSP object_sp); diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp index b891a34bd7c7..8e2c18ed42b4 100644 --- a/lldb/source/API/SBStructuredData.cpp +++ b/lldb/source/API/SBStructuredData.cpp @@ -232,3 +232,47 @@ lldb::SBScriptObject SBStructuredData::GetGenericValue() const { return {m_impl_up->GetGenericValue(), eScriptLanguageDefault}; } + +void SBStructuredData::SetValueForKey(const char *key, + SBStructuredData &value) { + LLDB_INSTRUMENT_VA(this, key, value); + + if (StructuredData::ObjectSP obj_sp = value.m_impl_up->GetObjectSP()) + m_impl_up->SetValueForKey(key, obj_sp); +} + +void SBStructuredData::SetUnsignedIntegerValue(uint64_t value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetUnsignedIntegerValue(value); +} + +void SBStructuredData::SetSignedIntegerValue(int64_t value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetSignedIntegerValue(value); +} + +void SBStructuredData::SetFloatValue(double value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetFloatValue(value); +} + +void SBStructuredData::SetBooleanValue(bool value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetBooleanValue(value); +} + +void SBStructuredData::SetStringValue(const char *value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetStringValue(value); +} + +void SBStructuredData::SetGenericValue(SBScriptObject value) { + LLDB_INSTRUMENT_VA(this, value); + + m_impl_up->SetGenericValue(value.GetPointer()); +} diff --git a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py index 21256d6c6e74..99f88d3da794 100644 --- a/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py +++ b/lldb/test/API/python_api/sbstructureddata/TestStructuredDataAPI.py @@ -10,7 +10,6 @@ from lldbsuite.test import lldbutil import json - class TestStructuredDataAPI(TestBase): NO_DEBUG_INFO_TESTCASE = True @@ -130,6 +129,52 @@ class TestStructuredDataAPI(TestBase): self.assertSuccess(example.SetFromJSON("null")) self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull) + example = lldb.SBStructuredData() + example.SetUnsignedIntegerValue(1) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger) + self.assertEqual(example.GetIntegerValue(), 1) + + example.SetSignedIntegerValue(-42) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeSignedInteger) + self.assertEqual(example.GetSignedIntegerValue(), -42) + + example.SetFloatValue(4.19) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat) + self.assertEqual(example.GetFloatValue(), 4.19) + + example.SetStringValue("Bonjour, 123!") + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString) + self.assertEqual(example.GetStringValue(42), "Bonjour, 123!") + + value = lldb.SBStructuredData() + example.SetValueForKey("Hello", value) + self.assertEqual(example.GetSize(), 0) + + nested_obj = lldb.SBStructuredData() + nested_obj.SetStringValue("World") + example.SetValueForKey("Hello", nested_obj) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeDictionary) + nested_obj = None + nested_obj = example.GetValueForKey("Hello") + self.assertTrue(nested_obj.IsValid()) + self.assertEqual(nested_obj.GetType(), lldb.eStructuredDataTypeString) + self.assertEqual(nested_obj.GetStringValue(42), "World") + + example.SetBooleanValue(True) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean) + self.assertTrue(example.GetBooleanValue()) + + rnd_obj = MyRandomClass() + stp = lldb.SBScriptObject(rnd_obj, lldb.eScriptLanguagePython) + self.assertEqual(stp.ptr, rnd_obj) + + example.SetGenericValue(stp) + self.assertEqual(example.GetType(), lldb.eStructuredDataTypeGeneric) + + my_random_class = example.GetGenericValue() + self.assertTrue(my_random_class) + self.assertEqual(my_random_class.payload, MyRandomClass.payload) + example_arr = [1, 2.3, "4", {"5": False}] arr_str = json.dumps(example_arr) s.Clear()