Skip to content

Commit 8f94995

Browse files
committed
[APIDigester] Allow outputting module differ diagnostics as JSON for other tools to consume
1 parent 972dc99 commit 8f94995

File tree

5 files changed

+435
-1
lines changed

5 files changed

+435
-1
lines changed

include/swift/APIDigester/ModuleDiagsConsumer.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "swift/AST/DiagnosticConsumer.h"
2424
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
2525

26+
#include "llvm/ADT/StringSet.h"
27+
#include "llvm/Support/JSON.h"
2628
#include "llvm/Support/raw_ostream.h"
2729
#include <set>
2830

@@ -42,6 +44,29 @@ class ModuleDifferDiagsConsumer: public PrintingDiagnosticConsumer {
4244
void handleDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) override;
4345
};
4446

47+
struct ModuleDifferDiagnosticInfo {
48+
DiagID ID;
49+
llvm::SmallString<256> Text;
50+
llvm::SmallString<32> Loc;
51+
52+
ModuleDifferDiagnosticInfo(DiagID ID, llvm::SmallString<256> Text,
53+
llvm::SmallString<32> Loc)
54+
: ID(ID), Text(Text), Loc(Loc) {}
55+
56+
void serialize(llvm::json::OStream &JSON);
57+
};
58+
59+
/// Diagnostic consumer that outputs module differ diags as JSON.
60+
class ModuleDifferDiagsJSONConsumer : public DiagnosticConsumer {
61+
llvm::raw_ostream &OS;
62+
std::vector<ModuleDifferDiagnosticInfo> AllDiags;
63+
64+
public:
65+
ModuleDifferDiagsJSONConsumer(llvm::raw_ostream &OS) : OS(OS){};
66+
~ModuleDifferDiagsJSONConsumer();
67+
void handleDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) override;
68+
};
69+
4570
class FilteringDiagnosticConsumer: public DiagnosticConsumer {
4671
bool HasError = false;
4772
std::unique_ptr<DiagnosticConsumer> subConsumer;

lib/APIDigester/ModuleDiagsConsumer.cpp

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18+
#include "swift/APIDigester/ModuleDiagsConsumer.h"
1819
#include "swift/AST/DiagnosticEngine.h"
1920
#include "swift/AST/DiagnosticsModuleDiffer.h"
20-
#include "swift/APIDigester/ModuleDiagsConsumer.h"
21+
#include "swift/Basic/SourceManager.h"
2122

2223
using namespace swift;
2324

@@ -81,6 +82,81 @@ static StringRef getCategoryName(uint32_t ID) {
8182
return "/* Others */";
8283
}
8384
}
85+
86+
static StringRef getSerializedIdentifier(uint32_t ID) {
87+
switch (ID) {
88+
case LocalDiagID::removed_decl:
89+
return "removedDecl";
90+
case LocalDiagID::moved_decl:
91+
return "movedDecl";
92+
case LocalDiagID::decl_kind_changed:
93+
return "declKindChanged";
94+
case LocalDiagID::renamed_decl:
95+
return "renamedDecl";
96+
case LocalDiagID::objc_name_change:
97+
return "objcNameChange";
98+
case LocalDiagID::decl_attr_change:
99+
return "declAttrChange";
100+
case LocalDiagID::decl_new_attr:
101+
return "declNewAttr";
102+
case LocalDiagID::func_self_access_change:
103+
return "funcSelfAccessChange";
104+
case LocalDiagID::new_decl_without_intro:
105+
return "newDeclWithoutIntro";
106+
case LocalDiagID::default_arg_removed:
107+
return "defaultArgRemoved";
108+
case LocalDiagID::decl_type_change:
109+
return "declTypeChange";
110+
case LocalDiagID::func_type_escaping_changed:
111+
return "funcTypeEscapingChanged";
112+
case LocalDiagID::param_ownership_change:
113+
return "paramOwnershipChange";
114+
case LocalDiagID::type_witness_change:
115+
return "typeWitnessChange";
116+
case LocalDiagID::raw_type_change:
117+
return "rawTypeChange";
118+
case LocalDiagID::generic_sig_change:
119+
return "genericSigChange";
120+
case LocalDiagID::enum_case_added:
121+
return "enumCaseAdded";
122+
case LocalDiagID::decl_added:
123+
return "declAdded";
124+
case LocalDiagID::decl_reorder:
125+
return "declReorder";
126+
case LocalDiagID::var_has_fixed_order_change:
127+
return "varHasFixedOrderChange";
128+
case LocalDiagID::func_has_fixed_order_change:
129+
return "funcHasFixedOrderChange";
130+
case LocalDiagID::conformance_added:
131+
return "conformanceAdded";
132+
case LocalDiagID::conformance_removed:
133+
return "conformanceRemoved";
134+
case LocalDiagID::optional_req_changed:
135+
return "optionalReqChanged";
136+
case LocalDiagID::existing_conformance_added:
137+
return "existingConformanceAdded";
138+
case LocalDiagID::default_associated_type_removed:
139+
return "defaultAssociatedTypeRemoved";
140+
case LocalDiagID::protocol_req_added:
141+
return "protocolReqAdded";
142+
case LocalDiagID::decl_new_witness_table_entry:
143+
return "declNewWitnessTableEntry";
144+
case LocalDiagID::super_class_removed:
145+
return "superClassRemoved";
146+
case LocalDiagID::super_class_changed:
147+
return "superClassChanged";
148+
case LocalDiagID::no_longer_open:
149+
return "noLongerOpen";
150+
case LocalDiagID::desig_init_added:
151+
return "desigInitAdded";
152+
case LocalDiagID::added_invisible_designated_init:
153+
return "addedInvisibleDesignatedInit";
154+
case LocalDiagID::not_inheriting_convenience_inits:
155+
return "notInheritingConvenienceInits";
156+
default:
157+
return "other";
158+
}
159+
}
84160
}
85161

86162
swift::ide::api::
@@ -123,6 +199,49 @@ swift::ide::api::ModuleDifferDiagsConsumer::~ModuleDifferDiagsConsumer() {
123199
}
124200
}
125201

202+
void swift::ide::api::ModuleDifferDiagnosticInfo::serialize(
203+
llvm::json::OStream &JSON) {
204+
JSON.object([&]() {
205+
JSON.attribute("identifier", getSerializedIdentifier((uint32_t)ID));
206+
JSON.attribute("text", Text);
207+
JSON.attribute("location", Loc);
208+
});
209+
}
210+
211+
void swift::ide::api::ModuleDifferDiagsJSONConsumer::handleDiagnostic(
212+
SourceManager &SM, const DiagnosticInfo &Info) {
213+
llvm::SmallString<256> Text;
214+
{
215+
llvm::raw_svector_ostream Out(Text);
216+
DiagnosticEngine::formatDiagnosticText(Out, Info.FormatString,
217+
Info.FormatArgs);
218+
}
219+
llvm::SmallString<32> Loc;
220+
if (Info.Loc.isValid()) {
221+
Loc = SM.getDisplayNameForLoc(Info.Loc);
222+
}
223+
AllDiags.push_back(ModuleDifferDiagnosticInfo(Info.ID, Text, Loc));
224+
}
225+
226+
swift::ide::api::ModuleDifferDiagsJSONConsumer::
227+
~ModuleDifferDiagsJSONConsumer() {
228+
llvm::json::OStream JSON(OS, 2);
229+
230+
JSON.object([&]() {
231+
JSON.attributeObject("version", [&]() {
232+
JSON.attribute("major", 0);
233+
JSON.attribute("minor", 1);
234+
});
235+
JSON.attributeArray("diagnostics", [&]() {
236+
for (auto &Info : AllDiags) {
237+
Info.serialize(JSON);
238+
}
239+
});
240+
});
241+
242+
JSON.flush();
243+
}
244+
126245
bool swift::ide::api::
127246
FilteringDiagnosticConsumer::shouldProceed(const DiagnosticInfo &Info) {
128247
if (allowedBreakages->empty()) {

0 commit comments

Comments
 (0)