24
24
#include " swift/Frontend/FrontendOptions.h"
25
25
#include " swift/IDE/SourceEntityWalker.h"
26
26
27
- #include " clang/Basic/Module.h"
28
27
#include " clang/AST/DeclObjC.h"
28
+ #include " clang/Basic/Module.h"
29
29
30
30
#include " llvm/ADT/SmallPtrSet.h"
31
31
#include " llvm/ADT/SmallString.h"
32
+ #include " llvm/Support/JSON.h"
32
33
#include " llvm/Support/Path.h"
33
34
#include " llvm/Support/YAMLTraits.h"
34
35
#include " llvm/Support/FileUtilities.h"
@@ -814,49 +815,50 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
814
815
return false ;
815
816
}
816
817
817
-
818
- bool swift::emitObjCMessageSendTraceIfNeeded (ModuleDecl *mainModule,
819
- const FrontendOptions &opts) {
820
- ASTContext &ctxt = mainModule->getASTContext ();
821
- assert (!ctxt.hadError () &&
822
- " We should've already exited earlier if there was an error." );
823
- class ObjcMethodRefereceCollector : public SourceEntityWalker {
824
- std::set<const clang::ObjCMethodDecl*> results;
825
- bool visitDeclReference (ValueDecl *D, CharSourceRange Range,
826
- TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef,
827
- Type T, ReferenceMetaData Data) override {
828
- if (!Range.isValid ())
829
- return true ;
830
- if (auto *clangD = dyn_cast_or_null<clang::ObjCMethodDecl>(D->getClangDecl ())) {
831
- results.insert (clangD);
832
- }
818
+ class ObjcMethodReferenceCollector : public SourceEntityWalker {
819
+ llvm::DenseSet<const clang::ObjCMethodDecl*> results;
820
+ bool visitDeclReference (ValueDecl *D, CharSourceRange Range,
821
+ TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef,
822
+ Type T, ReferenceMetaData Data) override {
823
+ if (!Range.isValid ())
833
824
return true ;
825
+ if (auto *clangD = dyn_cast_or_null<clang::ObjCMethodDecl>(D->getClangDecl ())) {
826
+ results.insert (clangD);
834
827
}
835
- public:
836
- void dump (llvm::raw_ostream &OS) {
837
- OS << " [\n " ;
828
+ return true ;
829
+ }
830
+ public:
831
+ void serializeAsJson (llvm::raw_ostream &OS) {
832
+ llvm::json::OStream out (OS, /* IndentSize=*/ 4 );
833
+ out.array ([&] {
838
834
for (const clang::ObjCMethodDecl* clangD: results) {
839
835
auto &SM = clangD->getASTContext ().getSourceManager ();
840
836
clang::SourceLocation Loc = clangD->getLocation ();
841
837
if (!Loc.isValid ()) {
842
838
continue ;
843
839
}
844
- OS << " \t {\n " ;
845
- OS << " \t\t\" method_name\" : \" " << clangD->getNameAsString () << " \" ,\n " ;
846
- OS << " \t\t\" location\" : \" " << Loc.printToString (SM) << " \"\n " ;
847
- OS << " \t }" ;
848
- OS << " ,\n " ;
840
+ out.object ([&] {
841
+ out.attribute (" Method" , clangD->getNameAsString ());
842
+ out.attribute (" location" , Loc.printToString (SM));
843
+ });
849
844
}
850
- OS << " {} ]\n " ;
851
- }
852
- };
845
+ });
846
+ }
847
+ };
848
+
849
+ bool swift::emitObjCMessageSendTraceIfNeeded (ModuleDecl *mainModule,
850
+ const FrontendOptions &opts) {
851
+ ASTContext &ctxt = mainModule->getASTContext ();
852
+ assert (!ctxt.hadError () &&
853
+ " We should've already exited earlier if there was an error." );
854
+
853
855
opts.InputsAndOutputs .forEachInput ([&](const InputFile &input) {
854
856
auto loadedModuleTracePath = input.getLoadedModuleTracePath ();
855
857
if (loadedModuleTracePath.empty ())
856
858
return false ;
857
859
llvm::SmallString<128 > tracePath {loadedModuleTracePath};
858
860
llvm::sys::path::remove_filename (tracePath);
859
- llvm::sys::path::append (tracePath, " SWIFT_OBJC_MESSAGE_TRACE" );
861
+ llvm::sys::path::append (tracePath, " . SWIFT_OBJC_MESSAGE_TRACE" );
860
862
if (!llvm::sys::fs::exists (tracePath)) {
861
863
if (llvm::sys::fs::create_directory (tracePath))
862
864
return false ;
@@ -868,13 +870,13 @@ bool swift::emitObjCMessageSendTraceIfNeeded(ModuleDecl *mainModule,
868
870
}
869
871
// Write the contents of the buffer.
870
872
llvm::raw_fd_ostream out (tmpFD, /* shouldClose=*/ true );
871
- ObjcMethodRefereceCollector collector;
873
+ ObjcMethodReferenceCollector collector;
872
874
for (auto *FU : mainModule->getFiles ()) {
873
875
if (auto *SF = dyn_cast<SourceFile>(FU)) {
874
876
collector.walk (*SF);
875
877
}
876
878
}
877
- collector.dump (out);
879
+ collector.serializeAsJson (out);
878
880
return true ;
879
881
});
880
882
return false ;
0 commit comments