Index: clang-tools-extra/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/clangd/CMakeLists.txt +++ clang-tools-extra/clangd/CMakeLists.txt @@ -18,6 +18,7 @@ unset(CLANGD_BUILD_XPC_DEFAULT) endif () +option(CLANGD_DECISION_FOREST "Enable decision forest model for ranking code completion items" ON) option(CLANGD_MALLOC_TRIM "Call malloc_trim(3) periodically in Clangd. (only takes effect when using glibc)" ON) # -DCLANG_TIDY_CHECKS=Off avoids a dependency on clang-tidy, reducing rebuilds. option(CLANGD_TIDY_CHECKS "Link all clang-tidy checks into clangd" ON) @@ -43,8 +44,13 @@ Option ) -include(${CMAKE_CURRENT_SOURCE_DIR}/quality/CompletionModel.cmake) -gen_decision_forest(${CMAKE_CURRENT_SOURCE_DIR}/quality/model CompletionModel clang::clangd::Example) +set(COMPLETIONMODEL_SOURCES) +if(CLANGD_DECISION_FOREST) + include(${CMAKE_CURRENT_SOURCE_DIR}/quality/CompletionModel.cmake) + gen_decision_forest(${CMAKE_CURRENT_SOURCE_DIR}/quality/model CompletionModel clang::clangd::Example) + list(APPEND COMPLETIONMODEL_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/CompletionModel.cpp) + add_definitions(-DCLANGD_DECISION_FOREST=1) +endif() if(MSVC AND NOT CLANG_CL) set_source_files_properties(CompileCommands.cpp PROPERTIES COMPILE_FLAGS -wd4130) # disables C4130: logical operation on address of string constant @@ -102,7 +108,7 @@ TUScheduler.cpp URI.cpp XRefs.cpp - ${CMAKE_CURRENT_BINARY_DIR}/CompletionModel.cpp + ${COMPLETIONMODEL_SOURCES} index/Background.cpp index/BackgroundIndexLoader.cpp Index: clang-tools-extra/clangd/CodeComplete.h =================================================================== --- clang-tools-extra/clangd/CodeComplete.h +++ clang-tools-extra/clangd/CodeComplete.h @@ -126,12 +126,21 @@ const SymbolRelevanceSignals &, float Score)> RecordCCResult; +#if defined(CLANGD_DECISION_FOREST) +# define DEFAULT_RANKING_MODEL DecisionForest +#else +# define DEFAULT_RANKING_MODEL Heuristics +#endif + /// Model to use for ranking code completion candidates. enum CodeCompletionRankingModel { Heuristics, +#if defined(CLANGD_DECISION_FOREST) DecisionForest, - } RankingModel = DecisionForest; +#endif + } RankingModel = DEFAULT_RANKING_MODEL; +#if defined(CLANGD_DECISION_FOREST) /// Callback used to score a CompletionCandidate if DecisionForest ranking /// model is enabled. /// This allows us to inject experimental models and compare them with @@ -148,6 +157,7 @@ /// Semantics: E.g. For Base = 1.3, if the Prediction score reduces by 2.6 /// points then completion score reduces by 50% or 1.3^(-2.6). float DecisionForestBase = 1.3f; +#endif }; // Semi-structured representation of a code-complete suggestion for our C++ API. Index: clang-tools-extra/clangd/CodeComplete.cpp =================================================================== --- clang-tools-extra/clangd/CodeComplete.cpp +++ clang-tools-extra/clangd/CodeComplete.cpp @@ -1844,12 +1844,14 @@ : Scores.Quality; return Scores; +#if defined(CLANGD_DECISION_FOREST) case RM::DecisionForest: DecisionForestScores DFScores = Opts.DecisionForestScorer( Quality, Relevance, Opts.DecisionForestBase); Scores.ExcludingName = DFScores.ExcludingName; Scores.Total = DFScores.Total; return Scores; +#endif } llvm_unreachable("Unhandled CodeCompletion ranking model."); } Index: clang-tools-extra/clangd/Quality.h =================================================================== --- clang-tools-extra/clangd/Quality.h +++ clang-tools-extra/clangd/Quality.h @@ -172,6 +172,7 @@ /// Combine symbol quality and relevance into a single score. float evaluateSymbolAndRelevance(float SymbolQuality, float SymbolRelevance); +#if defined(CLANGD_DECISION_FOREST) /// Same semantics as CodeComplete::Score. Quality score and Relevance score /// have been removed since DecisionForest cannot assign individual scores to /// Quality and Relevance signals. @@ -183,6 +184,7 @@ DecisionForestScores evaluateDecisionForest(const SymbolQualitySignals &Quality, const SymbolRelevanceSignals &Relevance, float Base); +#endif /// TopN is a lossy container that preserves only the "best" N elements. template > class TopN { Index: clang-tools-extra/clangd/Quality.cpp =================================================================== --- clang-tools-extra/clangd/Quality.cpp +++ clang-tools-extra/clangd/Quality.cpp @@ -9,7 +9,9 @@ #include "Quality.h" #include "AST.h" #include "ASTSignals.h" +#if defined(CLANGD_DECISION_FOREST) #include "CompletionModel.h" +#endif #include "FileDistance.h" #include "SourceCode.h" #include "index/Symbol.h" @@ -529,6 +531,7 @@ return SymbolQuality * SymbolRelevance; } +#if defined(CLANGD_DECISION_FOREST) DecisionForestScores evaluateDecisionForest(const SymbolQualitySignals &Quality, const SymbolRelevanceSignals &Relevance, float Base) { @@ -587,6 +590,7 @@ Scores.Total = Relevance.NameMatch * Scores.ExcludingName; return Scores; } +#endif // Produces an integer that sorts in the same order as F. // That is: a < b <==> encodeFloat(a) < encodeFloat(b). Index: clang-tools-extra/clangd/benchmarks/CMakeLists.txt =================================================================== --- clang-tools-extra/clangd/benchmarks/CMakeLists.txt +++ clang-tools-extra/clangd/benchmarks/CMakeLists.txt @@ -1,4 +1,6 @@ -add_subdirectory(CompletionModel) +if(CLANGD_DECISION_FOREST) + add_subdirectory(CompletionModel) +endif() add_benchmark(IndexBenchmark IndexBenchmark.cpp) Index: clang-tools-extra/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -209,10 +209,13 @@ "ranking-model", cat(Features), desc("Model to use to rank code-completion items"), - values(clEnumValN(CodeCompleteOptions::Heuristics, "heuristics", - "Use hueristics to rank code completion items"), + values( +#if defined(CLANGD_DECISION_FOREST) clEnumValN(CodeCompleteOptions::DecisionForest, "decision_forest", - "Use Decision Forest model to rank completion items")), + "Use Decision Forest model to rank completion items"), +#endif + clEnumValN(CodeCompleteOptions::Heuristics, "heuristics", + "Use hueristics to rank code completion items")), init(CodeCompleteOptions().RankingModel), Hidden, }; Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -170,6 +170,7 @@ return S; } +#if defined(CLANGD_DECISION_FOREST) TEST(DecisionForestRankingModel, NameMatchSanityTest) { clangd::CodeCompleteOptions Opts; Opts.RankingModel = CodeCompleteOptions::DecisionForest; @@ -230,6 +231,7 @@ EXPECT_NE(Results.Completions[0].Score.Total, MagicNumber); EXPECT_NE(Results.Completions[0].Score.ExcludingName, MagicNumber); } +#endif TEST(CompletionTest, Limit) { clangd::CodeCompleteOptions Opts;