|
27 | 27 | #include "swift/IDE/SourceEntityWalker.h" |
28 | 28 |
|
29 | 29 | #include "clang/AST/DeclObjC.h" |
| 30 | +#include "clang/AST/ObjCMethodReferenceInfo.h" |
30 | 31 | #include "clang/Basic/Module.h" |
31 | 32 |
|
32 | 33 | #include "llvm/ADT/SmallPtrSet.h" |
@@ -817,96 +818,38 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule, |
817 | 818 | return false; |
818 | 819 | } |
819 | 820 |
|
820 | | -const static unsigned OBJC_METHOD_TRACE_FILE_FORMAT_VERSION = 1; |
821 | | - |
822 | 821 | class ObjcMethodReferenceCollector: public SourceEntityWalker { |
823 | | - std::string compilerVer; |
824 | | - std::string target; |
825 | | - std::string targetVariant; |
826 | | - SmallVector<StringRef, 32> FilePaths; |
827 | 822 | unsigned CurrentFileID; |
828 | 823 | llvm::DenseMap<const clang::ObjCMethodDecl*, unsigned> results; |
829 | 824 | bool visitDeclReference(ValueDecl *D, CharSourceRange Range, |
830 | 825 | TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef, |
831 | 826 | Type T, ReferenceMetaData Data) override { |
832 | 827 | if (!Range.isValid()) |
833 | 828 | return true; |
834 | | - if (auto *clangD = dyn_cast_or_null<clang::ObjCMethodDecl>(D->getClangDecl())) { |
835 | | - results[clangD] = CurrentFileID; |
836 | | - } |
| 829 | + if (auto *clangD = dyn_cast_or_null<clang::ObjCMethodDecl>(D->getClangDecl())) |
| 830 | + Info.References[CurrentFileID].push_back(clangD); |
837 | 831 | return true; |
838 | 832 | } |
839 | | - static StringRef selectMethodKey(const clang::ObjCMethodDecl* clangD) { |
840 | | - assert(clangD); |
841 | | - if (clangD->isInstanceMethod()) |
842 | | - return "instance_method"; |
843 | | - else if (clangD->isClassMethod()) |
844 | | - return "class_method"; |
845 | | - else |
846 | | - return "method"; |
847 | | - } |
848 | | - static StringRef selectMethodOwnerKey(const clang::NamedDecl* clangD) { |
849 | | - assert(clangD); |
850 | | - if (isa<clang::ObjCInterfaceDecl>(clangD)) |
851 | | - return "interface_type"; |
852 | | - if (isa<clang::ObjCCategoryDecl>(clangD)) |
853 | | - return "category_type"; |
854 | | - if (isa<clang::ObjCProtocolDecl>(clangD)) |
855 | | - return "protocol_type"; |
856 | | - return "type"; |
857 | | - } |
| 833 | + |
| 834 | + clang::ObjCMethodReferenceInfo Info; |
| 835 | + |
858 | 836 | public: |
859 | 837 | ObjcMethodReferenceCollector(ModuleDecl *MD) { |
860 | | - compilerVer = |
| 838 | + Info.ToolName = "swift-compiler-version"; |
| 839 | + Info.ToolVersion = |
861 | 840 | getSwiftInterfaceCompilerVersionForCurrentCompiler(MD->getASTContext()); |
862 | 841 | auto &Opts = MD->getASTContext().LangOpts; |
863 | | - target = Opts.Target.str(); |
864 | | - targetVariant = Opts.TargetVariant.has_value() ? |
| 842 | + Info.Target = Opts.Target.str(); |
| 843 | + Info.TargetVariant = Opts.TargetVariant.has_value() ? |
865 | 844 | Opts.TargetVariant->str() : ""; |
866 | 845 | } |
867 | 846 | void setFileBeforeVisiting(SourceFile *SF) { |
868 | 847 | assert(SF && "need to visit actual source files"); |
869 | | - FilePaths.push_back(SF->getFilename()); |
870 | | - CurrentFileID = FilePaths.size(); |
| 848 | + Info.FilePaths.push_back(SF->getFilename().str()); |
| 849 | + CurrentFileID = Info.FilePaths.size(); |
871 | 850 | } |
872 | 851 | void serializeAsJson(llvm::raw_ostream &OS) { |
873 | | - llvm::json::OStream out(OS, /*IndentSize=*/4); |
874 | | - out.object([&] { |
875 | | - out.attribute("swift-compiler-version", compilerVer); |
876 | | - out.attribute("format-vesion", OBJC_METHOD_TRACE_FILE_FORMAT_VERSION); |
877 | | - out.attribute("target", target); |
878 | | - if (!targetVariant.empty()) |
879 | | - out.attribute("target-variant", targetVariant); |
880 | | - out.attributeArray("references", [&] { |
881 | | - for (auto pair: results) { |
882 | | - auto *clangD = pair.first; |
883 | | - auto &SM = clangD->getASTContext().getSourceManager(); |
884 | | - clang::SourceLocation Loc = clangD->getLocation(); |
885 | | - if (!Loc.isValid()) { |
886 | | - continue; |
887 | | - } |
888 | | - out.object([&] { |
889 | | - if (auto *parent = dyn_cast_or_null<clang::NamedDecl>(clangD |
890 | | - ->getParent())) { |
891 | | - auto pName = parent->getName(); |
892 | | - if (!pName.empty()) |
893 | | - out.attribute(selectMethodOwnerKey(parent), pName); |
894 | | - } |
895 | | - out.attribute(selectMethodKey(clangD), clangD->getNameAsString()); |
896 | | - out.attribute("declared_at", Loc.printToString(SM)); |
897 | | - out.attribute("referenced_at_file_id", pair.second); |
898 | | - }); |
899 | | - } |
900 | | - }); |
901 | | - out.attributeArray("fileMap", [&]{ |
902 | | - for (unsigned I = 0, N = FilePaths.size(); I != N; I ++) { |
903 | | - out.object([&] { |
904 | | - out.attribute("file_id", I + 1); |
905 | | - out.attribute("file_path", FilePaths[I]); |
906 | | - }); |
907 | | - } |
908 | | - }); |
909 | | - }); |
| 852 | + clang::serializeObjCMethodReferencesAsJson(Info, OS); |
910 | 853 | } |
911 | 854 | }; |
912 | 855 |
|
|
0 commit comments