21
21
#include " swift/Basic/Assertions.h"
22
22
#include " swift/Basic/FileTypes.h"
23
23
#include " swift/Basic/JSONSerialization.h"
24
+ #include " swift/Basic/SourceManager.h"
24
25
#include " swift/Frontend/FrontendOptions.h"
25
26
#include " swift/IDE/SourceEntityWalker.h"
26
27
@@ -815,7 +816,13 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
815
816
return false ;
816
817
}
817
818
819
+ const static unsigned OBJC_METHOD_TRACE_FILE_FORMAT_VERSION = 1 ;
820
+
818
821
class ObjcMethodReferenceCollector : public SourceEntityWalker {
822
+ std::string target;
823
+ std::string targetVariant;
824
+ SmallVector<StringRef, 32 > FilePaths;
825
+ unsigned CurrentFileID;
819
826
llvm::DenseSet<const clang::ObjCMethodDecl*> results;
820
827
bool visitDeclReference (ValueDecl *D, CharSourceRange Range,
821
828
TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef,
@@ -827,27 +834,70 @@ class ObjcMethodReferenceCollector: public SourceEntityWalker {
827
834
}
828
835
return true ;
829
836
}
837
+ static StringRef selectMethodKey (const clang::ObjCMethodDecl* clangD) {
838
+ assert (clangD);
839
+ if (clangD->isInstanceMethod ())
840
+ return " instance_method" ;
841
+ else if (clangD->isClassMethod ())
842
+ return " class_method" ;
843
+ else
844
+ return " method" ;
845
+ }
846
+ static StringRef selectMethodOwnerKey (const clang::NamedDecl* clangD) {
847
+ assert (clangD);
848
+ if (isa<clang::ObjCInterfaceDecl>(clangD))
849
+ return " interface_type" ;
850
+ if (isa<clang::ObjCCategoryDecl>(clangD))
851
+ return " category_type" ;
852
+ return " type" ;
853
+ }
830
854
public:
855
+ ObjcMethodReferenceCollector (ModuleDecl *MD) {
856
+ auto &Opts = MD->getASTContext ().LangOpts ;
857
+ target = Opts.Target .str ();
858
+ targetVariant = Opts.TargetVariant .has_value () ?
859
+ Opts.TargetVariant ->str () : " " ;
860
+ }
861
+ void setFileBeforeVisiting (SourceFile *SF) {
862
+ assert (SF && " need to visit actual source files" );
863
+ FilePaths.push_back (SF->getFilename ());
864
+ CurrentFileID = FilePaths.size ();
865
+ }
831
866
void serializeAsJson (llvm::raw_ostream &OS) {
832
867
llvm::json::OStream out (OS, /* IndentSize=*/ 4 );
833
- out.array ([&] {
834
- for (const clang::ObjCMethodDecl* clangD: results) {
835
- auto &SM = clangD->getASTContext ().getSourceManager ();
836
- clang::SourceLocation Loc = clangD->getLocation ();
837
- if (!Loc.isValid ()) {
838
- continue ;
839
- }
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);
868
+ out.object ([&] {
869
+ out.attribute (" format-vesion" , OBJC_METHOD_TRACE_FILE_FORMAT_VERSION);
870
+ out.attribute (" target" , target);
871
+ if (!targetVariant.empty ())
872
+ out.attribute (" target-variant" , targetVariant);
873
+ out.attributeArray (" references" , [&] {
874
+ for (const clang::ObjCMethodDecl* clangD: results) {
875
+ auto &SM = clangD->getASTContext ().getSourceManager ();
876
+ clang::SourceLocation Loc = clangD->getLocation ();
877
+ if (!Loc.isValid ()) {
878
+ continue ;
846
879
}
847
- out.attribute (" method" , clangD->getNameAsString ());
848
- out.attribute (" location" , Loc.printToString (SM));
849
- });
850
- }
880
+ out.object ([&] {
881
+ if (auto *parent = dyn_cast_or_null<clang::NamedDecl>(clangD
882
+ ->getParent ())) {
883
+ auto pName = parent->getName ();
884
+ if (!pName.empty ())
885
+ out.attribute (selectMethodOwnerKey (parent), pName);
886
+ }
887
+ out.attribute (selectMethodKey (clangD), clangD->getNameAsString ());
888
+ out.attribute (" declared_at" , Loc.printToString (SM));
889
+ out.attribute (" referenced_at_file_id" , CurrentFileID);
890
+ });
891
+ }
892
+ });
893
+ out.attributeArray (" fileMap" , [&]{
894
+ for (unsigned I = 0 , N = FilePaths.size (); I != N; I ++) {
895
+ out.object ([&] {
896
+ out.attribute (" file_id" , I + 1 );
897
+ out.attribute (" file_path" , FilePaths[I]);
898
+ });
899
+ }
900
+ });
851
901
});
852
902
}
853
903
};
@@ -864,7 +914,7 @@ bool swift::emitObjCMessageSendTraceIfNeeded(ModuleDecl *mainModule,
864
914
return false ;
865
915
llvm::SmallString<128 > tracePath {loadedModuleTracePath};
866
916
llvm::sys::path::remove_filename (tracePath);
867
- llvm::sys::path::append (tracePath, " .SWIFT_OBJC_MESSAGE_TRACE " );
917
+ llvm::sys::path::append (tracePath, " .SWIFT_FINE_DEPENDENCY_TRACE " );
868
918
if (!llvm::sys::fs::exists (tracePath)) {
869
919
if (llvm::sys::fs::create_directory (tracePath))
870
920
return false ;
@@ -876,9 +926,10 @@ bool swift::emitObjCMessageSendTraceIfNeeded(ModuleDecl *mainModule,
876
926
}
877
927
// Write the contents of the buffer.
878
928
llvm::raw_fd_ostream out (tmpFD, /* shouldClose=*/ true );
879
- ObjcMethodReferenceCollector collector;
929
+ ObjcMethodReferenceCollector collector (mainModule) ;
880
930
for (auto *FU : mainModule->getFiles ()) {
881
931
if (auto *SF = dyn_cast<SourceFile>(FU)) {
932
+ collector.setFileBeforeVisiting (SF);
882
933
collector.walk (*SF);
883
934
}
884
935
}
0 commit comments