@@ -42,7 +42,7 @@ static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s) {
4242}
4343
4444CommandReturnObject::CommandReturnObject (bool colors)
45- : m_out_stream(colors), m_err_stream(colors), m_diag_stream (colors) {}
45+ : m_out_stream(colors), m_err_stream(colors), m_colors (colors) {}
4646
4747void CommandReturnObject::AppendErrorWithFormat (const char *format, ...) {
4848 SetStatus (eReturnStatusFailed);
@@ -123,30 +123,79 @@ void CommandReturnObject::SetError(llvm::Error error) {
123123 }
124124}
125125
126- llvm::StringRef
127- CommandReturnObject::GetInlineDiagnosticString ( unsigned indent) {
128- RenderDiagnosticDetails (m_diag_stream , indent, true , m_diagnostics);
126+ std::string CommandReturnObject::GetInlineDiagnosticString ( unsigned indent) {
127+ StreamString diag_stream (m_colors);
128+ RenderDiagnosticDetails (diag_stream , indent, true , m_diagnostics);
129129 // Duplex the diagnostics to the secondary stream (but not inlined).
130- if (auto stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex ))
130+ if (auto stream_sp = m_err_stream.GetStreamAtIndex (eImmediateStreamIndex ))
131131 RenderDiagnosticDetails (*stream_sp, std::nullopt , false , m_diagnostics);
132132
133- // Clear them so GetErrorData() doesn't render them again.
134- m_diagnostics.clear ();
135- return m_diag_stream.GetString ();
133+ return diag_stream.GetString ().str ();
136134}
137135
138- llvm::StringRef CommandReturnObject::GetErrorString () {
139- // Diagnostics haven't been fetched; render them now (not inlined).
140- if (!m_diagnostics.empty ()) {
141- RenderDiagnosticDetails (GetErrorStream (), std::nullopt , false ,
142- m_diagnostics);
143- m_diagnostics.clear ();
144- }
136+ std::string CommandReturnObject::GetErrorString (bool with_diagnostics) {
137+ StreamString stream (m_colors);
138+ if (with_diagnostics)
139+ RenderDiagnosticDetails (stream, std::nullopt , false , m_diagnostics);
145140
146141 lldb::StreamSP stream_sp (m_err_stream.GetStreamAtIndex (eStreamStringIndex));
147142 if (stream_sp)
148- return std::static_pointer_cast<StreamString>(stream_sp)->GetString ();
149- return llvm::StringRef ();
143+ stream << std::static_pointer_cast<StreamString>(stream_sp)->GetString ();
144+ return stream.GetString ().str ();
145+ }
146+
147+ StructuredData::ObjectSP CommandReturnObject::GetErrorData () {
148+ auto make_array = []() { return std::make_unique<StructuredData::Array>(); };
149+ auto make_bool = [](bool b) {
150+ return std::make_unique<StructuredData::Boolean>(b);
151+ };
152+ auto make_dict = []() {
153+ return std::make_unique<StructuredData::Dictionary>();
154+ };
155+ auto make_int = [](unsigned i) {
156+ return std::make_unique<StructuredData::UnsignedInteger>(i);
157+ };
158+ auto make_string = [](llvm::StringRef s) {
159+ return std::make_unique<StructuredData::String>(s);
160+ };
161+ auto dict_up = make_dict ();
162+ dict_up->AddItem (" version" , make_int (1 ));
163+ auto array_up = make_array ();
164+ for (const DiagnosticDetail &diag : m_diagnostics) {
165+ auto detail_up = make_dict ();
166+ if (auto &sloc = diag.source_location ) {
167+ auto sloc_up = make_dict ();
168+ sloc_up->AddItem (" file" , make_string (sloc->file .GetPath ()));
169+ sloc_up->AddItem (" line" , make_int (sloc->line ));
170+ sloc_up->AddItem (" length" , make_int (sloc->length ));
171+ sloc_up->AddItem (" hidden" , make_bool (sloc->hidden ));
172+ sloc_up->AddItem (" in_user_input" , make_bool (sloc->in_user_input ));
173+ detail_up->AddItem (" source_location" , std::move (sloc_up));
174+ }
175+ llvm::StringRef severity = " unknown" ;
176+ switch (diag.severity ) {
177+ case lldb::eSeverityError:
178+ severity = " error" ;
179+ break ;
180+ case lldb::eSeverityWarning:
181+ severity = " warning" ;
182+ break ;
183+ case lldb::eSeverityInfo:
184+ severity = " note" ;
185+ break ;
186+ }
187+ detail_up->AddItem (" severity" , make_string (severity));
188+ detail_up->AddItem (" message" , make_string (diag.message ));
189+ detail_up->AddItem (" rendered" , make_string (diag.rendered ));
190+ array_up->AddItem (std::move (detail_up));
191+ }
192+ dict_up->AddItem (" details" , std::move (array_up));
193+ if (auto stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex)) {
194+ auto text = std::static_pointer_cast<StreamString>(stream_sp)->GetString ();
195+ if (!text.empty ())
196+ dict_up->AddItem (" text" , make_string (text));
197+ }
198+ return dict_up;
150199}
151200
152201// Similar to AppendError, but do not prepend 'Status: ' to message, and don't
@@ -179,6 +228,7 @@ void CommandReturnObject::Clear() {
179228 stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex);
180229 if (stream_sp)
181230 static_cast <StreamString *>(stream_sp.get ())->Clear ();
231+ m_diagnostics.clear ();
182232 m_status = eReturnStatusStarted;
183233 m_did_change_process_state = false ;
184234 m_suppress_immediate_output = false ;
0 commit comments