|
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