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,56 @@ 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
+ if (auto *parent = dyn_cast_or_null<clang::NamedDecl>(clangD
842
+ ->getParent ())) {
843
+ auto pName = parent->getName ();
844
+ if (!pName.empty ())
845
+ out.attribute (" type" , pName);
846
+ }
847
+ out.attribute (" method" , clangD->getNameAsString ());
848
+ out.attribute (" location" , Loc.printToString (SM));
849
+ });
849
850
}
850
- OS << " {} ]\n " ;
851
- }
852
- };
851
+ });
852
+ }
853
+ };
854
+
855
+ bool swift::emitObjCMessageSendTraceIfNeeded (ModuleDecl *mainModule,
856
+ const FrontendOptions &opts) {
857
+ ASTContext &ctxt = mainModule->getASTContext ();
858
+ assert (!ctxt.hadError () &&
859
+ " We should've already exited earlier if there was an error." );
860
+
853
861
opts.InputsAndOutputs .forEachInput ([&](const InputFile &input) {
854
862
auto loadedModuleTracePath = input.getLoadedModuleTracePath ();
855
863
if (loadedModuleTracePath.empty ())
856
864
return false ;
857
865
llvm::SmallString<128 > tracePath {loadedModuleTracePath};
858
866
llvm::sys::path::remove_filename (tracePath);
859
- llvm::sys::path::append (tracePath, " SWIFT_OBJC_MESSAGE_TRACE" );
867
+ llvm::sys::path::append (tracePath, " . SWIFT_OBJC_MESSAGE_TRACE" );
860
868
if (!llvm::sys::fs::exists (tracePath)) {
861
869
if (llvm::sys::fs::create_directory (tracePath))
862
870
return false ;
@@ -868,13 +876,13 @@ bool swift::emitObjCMessageSendTraceIfNeeded(ModuleDecl *mainModule,
868
876
}
869
877
// Write the contents of the buffer.
870
878
llvm::raw_fd_ostream out (tmpFD, /* shouldClose=*/ true );
871
- ObjcMethodRefereceCollector collector;
879
+ ObjcMethodReferenceCollector collector;
872
880
for (auto *FU : mainModule->getFiles ()) {
873
881
if (auto *SF = dyn_cast<SourceFile>(FU)) {
874
882
collector.walk (*SF);
875
883
}
876
884
}
877
- collector.dump (out);
885
+ collector.serializeAsJson (out);
878
886
return true ;
879
887
});
880
888
return false ;
0 commit comments