diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -786,7 +786,7 @@ }; Server->applyTweak(Params.tweakArgs->file.file(), Params.tweakArgs->selection, Params.tweakArgs->tweakID, - std::move(Action)); + DraftMgr, std::move(Action)); } else { // We should not get here because ExecuteCommandParams would not have // parsed in the first place and this handler should not be called. But if @@ -1064,7 +1064,7 @@ return Reply(llvm::json::Array(Commands)); }; Server->enumerateTweaks( - File.file(), Params.range, + File.file(), Params.range, DraftMgr, [this, KindAllowed(std::move(KindAllowed))](const Tweak &T) { return Opts.TweakFilter(T) && KindAllowed(T.kind()); }, diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -295,13 +295,13 @@ }; /// Enumerate the code tweaks available to the user at a specified point. /// Tweaks where Filter returns false will not be checked or included. - void enumerateTweaks(PathRef File, Range Sel, + void enumerateTweaks(PathRef File, Range Sel, const DraftStore &DraftMgr, llvm::unique_function Filter, Callback> CB); /// Apply the code tweak with a specified \p ID. void applyTweak(PathRef File, Range Sel, StringRef ID, - Callback CB); + const DraftStore &DraftMgr, Callback CB); /// Called when an event occurs for a watched file in the workspace. void onFileEvent(const DidChangeWatchedFilesParams &Params); diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -449,12 +449,13 @@ } void ClangdServer::enumerateTweaks( - PathRef File, Range Sel, llvm::unique_function Filter, + PathRef File, Range Sel, const DraftStore &DraftMgr, + llvm::unique_function Filter, Callback> CB) { // Tracks number of times a tweak has been offered. static constexpr trace::Metric TweakAvailable( "tweak_available", trace::Metric::Counter, "tweak_id"); - auto Action = [File = File.str(), Sel, CB = std::move(CB), + auto Action = [File = File.str(), Sel, &DraftMgr, CB = std::move(CB), Filter = std::move(Filter)](Expected InpAST) mutable { if (!InpAST) @@ -469,7 +470,7 @@ return Filter(T) && !PreparedTweaks.count(T.id()); }; for (const auto &Sel : *Selections) { - for (auto &T : prepareTweaks(*Sel, DeduplicatingFilter)) { + for (auto &T : prepareTweaks(*Sel, DraftMgr, DeduplicatingFilter)) { Res.push_back({T->id(), T->title(), T->kind()}); PreparedTweaks.insert(T->id()); TweakAvailable.record(1, T->id()); @@ -484,6 +485,7 @@ } void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, + const DraftStore &DraftMgr, Callback CB) { // Tracks number of times a tweak has been attempted. static constexpr trace::Metric TweakAttempt( @@ -493,7 +495,7 @@ "tweak_failed", trace::Metric::Counter, "tweak_id"); TweakAttempt.record(1, TweakID); auto Action = [File = File.str(), Sel, TweakID = TweakID.str(), - CB = std::move(CB), + CB = std::move(CB), &DraftMgr, this](Expected InpAST) mutable { if (!InpAST) return CB(InpAST.takeError()); @@ -504,9 +506,9 @@ // Try each selection, take the first one that prepare()s. // If they all fail, Effect will hold get the last error. for (const auto &Selection : *Selections) { - auto T = prepareTweak(TweakID, *Selection); + auto T = prepareTweak(TweakID, *Selection, DraftMgr); if (T) { - Effect = (*T)->apply(*Selection); + Effect = (*T)->apply(*Selection, DraftMgr); break; } Effect = T.takeError(); diff --git a/clang-tools-extra/clangd/refactor/Tweak.h b/clang-tools-extra/clangd/refactor/Tweak.h --- a/clang-tools-extra/clangd/refactor/Tweak.h +++ b/clang-tools-extra/clangd/refactor/Tweak.h @@ -35,6 +35,8 @@ namespace clang { namespace clangd { +class DraftStore; + /// An interface base for small context-sensitive refactoring actions. /// To implement a new tweak use the following pattern in a .cpp file: /// class MyTweak : public Tweak { @@ -102,10 +104,11 @@ /// This function should be fast, if the action requires non-trivial work it /// should be moved into 'apply'. /// Returns true iff the action is available and apply() can be called on it. - virtual bool prepare(const Selection &Sel) = 0; + virtual bool prepare(const Selection &Sel, const DraftStore &DraftMgr) = 0; /// Run the second stage of the action that would produce the actual effect. /// EXPECTS: prepare() was called and returned true. - virtual Expected apply(const Selection &Sel) = 0; + virtual Expected apply(const Selection &Sel, + const DraftStore &DraftMgr) = 0; /// A one-line title of the action that should be shown to the users in the /// UI. @@ -127,14 +130,15 @@ /// Calls prepare() on all tweaks that satisfy the filter, returning those that /// can run on the selection. std::vector> -prepareTweaks(const Tweak::Selection &S, +prepareTweaks(const Tweak::Selection &S, const DraftStore &DraftMgr, llvm::function_ref Filter); // Calls prepare() on the tweak with a given ID. // If prepare() returns false, returns an error. // If prepare() returns true, returns the corresponding tweak. llvm::Expected> prepareTweak(StringRef TweakID, - const Tweak::Selection &S); + const Tweak::Selection &S, + const DraftStore &DraftMgr); } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/refactor/Tweak.cpp b/clang-tools-extra/clangd/refactor/Tweak.cpp --- a/clang-tools-extra/clangd/refactor/Tweak.cpp +++ b/clang-tools-extra/clangd/refactor/Tweak.cpp @@ -56,14 +56,14 @@ } std::vector> -prepareTweaks(const Tweak::Selection &S, +prepareTweaks(const Tweak::Selection &S, const DraftStore &DraftMgr, llvm::function_ref Filter) { validateRegistry(); std::vector> Available; for (const auto &E : TweakRegistry::entries()) { std::unique_ptr T = E.instantiate(); - if (!Filter(*T) || !T->prepare(S)) + if (!Filter(*T) || !T->prepare(S, DraftMgr)) continue; Available.push_back(std::move(T)); } @@ -74,15 +74,16 @@ return Available; } -llvm::Expected> prepareTweak(StringRef ID, - const Tweak::Selection &S) { +llvm::Expected> +prepareTweak(StringRef ID, const Tweak::Selection &S, + const DraftStore &DraftMgr) { auto It = llvm::find_if( TweakRegistry::entries(), [ID](const TweakRegistry::entry &E) { return E.getName() == ID; }); if (It == TweakRegistry::end()) return error("tweak ID {0} is invalid", ID); std::unique_ptr T = It->instantiate(); - if (!T->prepare(S)) + if (!T->prepare(S, DraftMgr)) return error("failed to prepare() tweak {0}", ID); return std::move(T); } diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -35,8 +35,8 @@ public: const char *id() const override; - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override; llvm::StringLiteral kind() const override { return CodeAction::REFACTOR_KIND; @@ -230,7 +230,7 @@ return OutStream.str(); } -bool AddUsing::prepare(const Selection &Inputs) { +bool AddUsing::prepare(const Selection &Inputs, const DraftStore &) { auto &SM = Inputs.AST->getSourceManager(); const auto &TB = Inputs.AST->getTokens(); @@ -327,7 +327,8 @@ return true; } -Expected AddUsing::apply(const Selection &Inputs) { +Expected AddUsing::apply(const Selection &Inputs, + const DraftStore &) { auto &SM = Inputs.AST->getSourceManager(); std::string QualifierToRemoveStr = getNNSLAsString( diff --git a/clang-tools-extra/clangd/refactor/tweaks/AnnotateHighlightings.cpp b/clang-tools-extra/clangd/refactor/tweaks/AnnotateHighlightings.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/AnnotateHighlightings.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AnnotateHighlightings.cpp @@ -24,8 +24,10 @@ public: const char *id() const override final; - bool prepare(const Selection &Inputs) override { return true; } - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override { + return true; + } + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return "Annotate highlighting tokens"; } llvm::StringLiteral kind() const override { @@ -35,7 +37,8 @@ }; REGISTER_TWEAK(AnnotateHighlightings) -Expected AnnotateHighlightings::apply(const Selection &Inputs) { +Expected AnnotateHighlightings::apply(const Selection &Inputs, + const DraftStore &) { const Decl *CommonDecl = nullptr; for (auto N = Inputs.ASTSelection.commonAncestor(); N && !CommonDecl; N = N->Parent) diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp @@ -403,7 +403,7 @@ // Returns true when selection is on a function definition that does not // make use of any internal symbols. - bool prepare(const Selection &Sel) override { + bool prepare(const Selection &Sel, const DraftStore &) override { const SelectionTree::Node *SelNode = Sel.ASTSelection.commonAncestor(); if (!SelNode) return false; @@ -442,7 +442,7 @@ return true; } - Expected apply(const Selection &Sel) override { + Expected apply(const Selection &Sel, const DraftStore &) override { const auto &AST = Sel.AST->getASTContext(); const auto &SM = AST.getSourceManager(); diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -363,7 +363,7 @@ return "Move function body to out-of-line"; } - bool prepare(const Selection &Sel) override { + bool prepare(const Selection &Sel, const DraftStore &) override { // Bail out if we are not in a header file. // FIXME: We might want to consider moving method definitions below class // definition even if we are inside a source file. @@ -397,7 +397,7 @@ return true; } - Expected apply(const Selection &Sel) override { + Expected apply(const Selection &Sel, const DraftStore &) override { const SourceManager &SM = Sel.AST->getSourceManager(); auto MainFileName = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); diff --git a/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp b/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp @@ -33,14 +33,14 @@ public: const char *id() const override final; - bool prepare(const Selection &Inputs) override { + bool prepare(const Selection &Inputs, const DraftStore &) override { for (auto N = Inputs.ASTSelection.commonAncestor(); N && !Node; N = N->Parent) if (dumpable(N->ASTNode)) Node = N->ASTNode; return Node.hasValue(); } - Expected apply(const Selection &Inputs) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return std::string( llvm::formatv("Dump {0} AST", Node->getNodeKind().asStringRef())); @@ -59,7 +59,8 @@ }; REGISTER_TWEAK(DumpAST) -llvm::Expected DumpAST::apply(const Selection &Inputs) { +llvm::Expected DumpAST::apply(const Selection &Inputs, + const DraftStore &) { std::string Str; llvm::raw_string_ostream OS(Str); Node->dump(OS, Inputs.AST->getASTContext()); @@ -86,8 +87,10 @@ public: const char *id() const override final; - bool prepare(const Selection &Inputs) override { return true; } - Expected apply(const Selection &Inputs) override { + bool prepare(const Selection &Inputs, const DraftStore &) override { + return true; + } + Expected apply(const Selection &Inputs, const DraftStore &) override { return Effect::showMessage(llvm::to_string(Inputs.ASTSelection)); } std::string title() const override { return "Show selection tree"; } @@ -105,8 +108,10 @@ /// {"containerName":null,"id":"CA2EBE44A1D76D2A","name":"foo","usr":"c:@F@foo#"} class DumpSymbol : public Tweak { const char *id() const override final; - bool prepare(const Selection &Inputs) override { return true; } - Expected apply(const Selection &Inputs) override { + bool prepare(const Selection &Inputs, const DraftStore &) override { + return true; + } + Expected apply(const Selection &Inputs, const DraftStore &) override { std::string Storage; llvm::raw_string_ostream Out(Storage); @@ -135,14 +140,14 @@ public: const char *id() const override final; - bool prepare(const Selection &Inputs) override { + bool prepare(const Selection &Inputs, const DraftStore &) override { if (auto *Node = Inputs.ASTSelection.commonAncestor()) if (auto *D = Node->ASTNode.get()) Record = dyn_cast(D); return Record && Record->isThisDeclarationADefinition() && !Record->isDependentType(); } - Expected apply(const Selection &Inputs) override { + Expected apply(const Selection &Inputs, const DraftStore &) override { std::string Str; llvm::raw_string_ostream OS(Str); Inputs.AST->getASTContext().DumpRecordLayout(Record, OS); diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp @@ -40,8 +40,8 @@ llvm::StringLiteral kind() const override { return CodeAction::REFACTOR_KIND; } - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override; private: @@ -82,7 +82,7 @@ return false; } -bool ExpandAutoType::prepare(const Selection& Inputs) { +bool ExpandAutoType::prepare(const Selection &Inputs, const DraftStore &) { CachedLocation = llvm::None; if (auto *Node = Inputs.ASTSelection.commonAncestor()) { if (auto *TypeNode = Node->ASTNode.get()) { @@ -99,7 +99,8 @@ return (bool) CachedLocation; } -Expected ExpandAutoType::apply(const Selection& Inputs) { +Expected ExpandAutoType::apply(const Selection &Inputs, + const DraftStore &) { auto &SrcMgr = Inputs.AST->getSourceManager(); llvm::Optional DeducedType = getDeducedType( diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExpandMacro.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExpandMacro.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/ExpandMacro.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExpandMacro.cpp @@ -35,8 +35,9 @@ return CodeAction::REFACTOR_KIND; } - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, + const DraftStore &) override; std::string title() const override; private: @@ -87,7 +88,7 @@ return T; } -bool ExpandMacro::prepare(const Selection &Inputs) { +bool ExpandMacro::prepare(const Selection &Inputs, const DraftStore &) { // FIXME: we currently succeed on selection at the end of the token, e.g. // 'FOO[[ ]]BAR'. We should not trigger in that case. @@ -105,7 +106,8 @@ return true; } -Expected ExpandMacro::apply(const Selection &Inputs) { +Expected ExpandMacro::apply(const Selection &Inputs, + const DraftStore &) { auto &SM = Inputs.AST->getSourceManager(); std::string Replacement; diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp @@ -682,8 +682,8 @@ class ExtractFunction : public Tweak { public: const char *id() const override final; - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return "Extract to function"; } llvm::StringLiteral kind() const override { return CodeAction::REFACTOR_KIND; @@ -729,7 +729,7 @@ return V.Found; } -bool ExtractFunction::prepare(const Selection &Inputs) { +bool ExtractFunction::prepare(const Selection &Inputs, const DraftStore &) { const LangOptions &LangOpts = Inputs.AST->getLangOpts(); if (!LangOpts.CPlusPlus) return false; @@ -748,7 +748,8 @@ return true; } -Expected ExtractFunction::apply(const Selection &Inputs) { +Expected ExtractFunction::apply(const Selection &Inputs, + const DraftStore &) { const SourceManager &SM = Inputs.AST->getSourceManager(); const LangOptions &LangOpts = Inputs.AST->getLangOpts(); auto ExtractedFunc = getExtractedFunction(ExtZone, SM, LangOpts); diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp @@ -443,8 +443,8 @@ class ExtractVariable : public Tweak { public: const char *id() const override final; - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return "Extract subexpression to variable"; } @@ -457,7 +457,7 @@ std::unique_ptr Target; }; REGISTER_TWEAK(ExtractVariable) -bool ExtractVariable::prepare(const Selection &Inputs) { +bool ExtractVariable::prepare(const Selection &Inputs, const DraftStore &) { // we don't trigger on empty selections for now if (Inputs.SelectionBegin == Inputs.SelectionEnd) return false; @@ -473,7 +473,8 @@ return Target && Target->isExtractable(); } -Expected ExtractVariable::apply(const Selection &Inputs) { +Expected ExtractVariable::apply(const Selection &Inputs, + const DraftStore &) { tooling::Replacements Result; // FIXME: get variable name from user or suggest based on type std::string VarName = "dummy"; diff --git a/clang-tools-extra/clangd/refactor/tweaks/ObjCLocalizeStringLiteral.cpp b/clang-tools-extra/clangd/refactor/tweaks/ObjCLocalizeStringLiteral.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/ObjCLocalizeStringLiteral.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ObjCLocalizeStringLiteral.cpp @@ -39,8 +39,9 @@ return CodeAction::REFACTOR_KIND; } - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, + const DraftStore &) override; std::string title() const override; private: @@ -49,7 +50,8 @@ REGISTER_TWEAK(ObjCLocalizeStringLiteral) -bool ObjCLocalizeStringLiteral::prepare(const Selection &Inputs) { +bool ObjCLocalizeStringLiteral::prepare(const Selection &Inputs, + const DraftStore &) { const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor(); if (!N) return false; @@ -64,7 +66,7 @@ } Expected -ObjCLocalizeStringLiteral::apply(const Selection &Inputs) { +ObjCLocalizeStringLiteral::apply(const Selection &Inputs, const DraftStore &) { auto *AST = Inputs.AST; auto &SM = AST->getSourceManager(); const auto &TB = AST->getTokens(); diff --git a/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp b/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp @@ -50,8 +50,8 @@ namespace { class PopulateSwitch : public Tweak { const char *id() const override; - bool prepare(const Selection &Sel) override; - Expected apply(const Selection &Sel) override; + bool prepare(const Selection &Sel, const DraftStore &) override; + Expected apply(const Selection &Sel, const DraftStore &) override; std::string title() const override { return "Populate switch"; } llvm::StringLiteral kind() const override { return CodeAction::QUICKFIX_KIND; @@ -83,7 +83,7 @@ REGISTER_TWEAK(PopulateSwitch) -bool PopulateSwitch::prepare(const Selection &Sel) { +bool PopulateSwitch::prepare(const Selection &Sel, const DraftStore &) { const SelectionTree::Node *CA = Sel.ASTSelection.commonAncestor(); if (!CA) return false; @@ -179,7 +179,8 @@ [](auto &Pair) { return Pair.second.isCovered(); }); } -Expected PopulateSwitch::apply(const Selection &Sel) { +Expected PopulateSwitch::apply(const Selection &Sel, + const DraftStore &) { ASTContext &Ctx = Sel.AST->getASTContext(); SourceLocation Loc = Body->getRBracLoc(); diff --git a/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp b/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/RawStringLiteral.cpp @@ -38,8 +38,8 @@ public: const char *id() const override final; - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return "Convert to raw string"; } llvm::StringLiteral kind() const override { return CodeAction::REFACTOR_KIND; @@ -79,7 +79,7 @@ return !Content.contains(")\""); } -bool RawStringLiteral::prepare(const Selection &Inputs) { +bool RawStringLiteral::prepare(const Selection &Inputs, const DraftStore &) { const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor(); if (!N) return false; @@ -89,7 +89,8 @@ needsRaw(Str->getBytes()) && canBeRaw(Str->getBytes()); } -Expected RawStringLiteral::apply(const Selection &Inputs) { +Expected RawStringLiteral::apply(const Selection &Inputs, + const DraftStore &) { auto &SM = Inputs.AST->getSourceManager(); auto Reps = tooling::Replacements( tooling::Replacement(SM, Str, ("R\"(" + Str->getBytes() + ")\"").str(), diff --git a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp @@ -36,8 +36,8 @@ public: const char *id() const override; - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return "Remove using namespace, re-qualify names instead"; } @@ -104,7 +104,8 @@ return D; } -bool RemoveUsingNamespace::prepare(const Selection &Inputs) { +bool RemoveUsingNamespace::prepare(const Selection &Inputs, + const DraftStore &) { // Find the 'using namespace' directive under the cursor. auto *CA = Inputs.ASTSelection.commonAncestor(); if (!CA) @@ -129,7 +130,8 @@ return isTopLevelDecl(CA); } -Expected RemoveUsingNamespace::apply(const Selection &Inputs) { +Expected RemoveUsingNamespace::apply(const Selection &Inputs, + const DraftStore &) { auto &Ctx = Inputs.AST->getASTContext(); auto &SM = Ctx.getSourceManager(); // First, collect *all* using namespace directives that redeclare the same diff --git a/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp b/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -36,8 +36,8 @@ public: const char *id() const override final; - bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; + bool prepare(const Selection &Inputs, const DraftStore &) override; + Expected apply(const Selection &Inputs, const DraftStore &) override; std::string title() const override { return "Swap if branches"; } llvm::StringLiteral kind() const override { return CodeAction::REFACTOR_KIND; @@ -50,7 +50,7 @@ REGISTER_TWEAK(SwapIfBranches) -bool SwapIfBranches::prepare(const Selection &Inputs) { +bool SwapIfBranches::prepare(const Selection &Inputs, const DraftStore &) { for (const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor(); N && !If; N = N->Parent) { // Stop once we hit a block, e.g. a lambda in the if condition. @@ -64,7 +64,8 @@ dyn_cast_or_null(If->getElse()); } -Expected SwapIfBranches::apply(const Selection &Inputs) { +Expected SwapIfBranches::apply(const Selection &Inputs, + const DraftStore &) { auto &Ctx = Inputs.AST->getASTContext(); auto &SrcMgr = Inputs.AST->getSourceManager(); diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -193,6 +193,8 @@ log("Testing features at each token (may be slow in large files)"); auto SpelledTokens = AST->getTokens().spelledTokens(AST->getSourceManager().getMainFileID()); + + DraftStore EmptyDrafts; for (const auto &Tok : SpelledTokens) { unsigned Start = AST->getSourceManager().getFileOffset(Tok.location()); unsigned End = Start + Tok.length(); @@ -203,8 +205,9 @@ auto Tree = SelectionTree::createRight(AST->getASTContext(), AST->getTokens(), Start, End); Tweak::Selection Selection(&Index, *AST, Start, End, std::move(Tree)); - for (const auto &T : prepareTweaks(Selection, Opts.TweakFilter)) { - auto Result = T->apply(Selection); + for (const auto &T : + prepareTweaks(Selection, EmptyDrafts, Opts.TweakFilter)) { + auto Result = T->apply(Selection, EmptyDrafts); if (!Result) { elog(" tweak: {0} ==> FAIL: {1}", T->id(), Result.takeError()); ++ErrCount; diff --git a/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp --- a/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp @@ -9,6 +9,7 @@ #include "TweakTesting.h" #include "Annotations.h" +#include "DraftStore.h" #include "SourceCode.h" #include "TestFS.h" #include "refactor/Tweak.h" @@ -70,13 +71,15 @@ applyTweak(ParsedAST &AST, const Annotations &Input, StringRef TweakID, const SymbolIndex *Index) { auto Range = rangeOrPoint(Input); + DraftStore EmptyDrafts; llvm::Optional> Result; SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Range.first, Range.second, [&](SelectionTree ST) { Tweak::Selection S(Index, AST, Range.first, Range.second, std::move(ST)); - if (auto T = prepareTweak(TweakID, S)) { - Result = (*T)->apply(S); + if (auto T = + prepareTweak(TweakID, S, EmptyDrafts)) { + Result = (*T)->apply(S, EmptyDrafts); return true; } else { llvm::consumeError(T.takeError());