VitaNuo created this revision.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
VitaNuo requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D144862
Files:
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdLSPServer.h
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/XRefs.h
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -32,6 +32,8 @@
namespace clangd {
class ParsedAST;
+std::vector<CodeLens> findCodeLens(ParsedAST &AST);
+
// Describes where a symbol is declared and defined (as far as clangd knows).
// There are three cases:
// - a declaration only, no definition is known (e.g. only header seen)
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -16,6 +16,8 @@
#include "Selection.h"
#include "SourceCode.h"
#include "URI.h"
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Types.h"
#include "index/Index.h"
#include "index/Merge.h"
#include "index/Relation.h"
@@ -62,9 +64,11 @@
#include "llvm/Support/raw_ostream.h"
#include <optional>
#include <vector>
+#include <string>
namespace clang {
namespace clangd {
+std::string HelloString = "Hello";
namespace {
// Returns the single definition of the entity declared by D, if visible.
@@ -74,6 +78,7 @@
// Kinds of nodes that always return nullptr here will not have definitions
// reported by locateSymbolAt().
const NamedDecl *getDefinition(const NamedDecl *D) {
+ std::string AnotherString;
assert(D);
// Decl has one definition that we can find.
if (const auto *TD = dyn_cast<TagDecl>(D))
@@ -118,6 +123,7 @@
// FindSymbols.
std::optional<Location> toLSPLocation(const SymbolLocation &Loc,
llvm::StringRef TUPath) {
+ std::string ThirdString;
if (!Loc)
return std::nullopt;
auto Uri = URI::parse(Loc.FileURI);
@@ -1213,8 +1219,50 @@
return std::nullopt;
}
+std::vector<include_cleaner::SymbolReference>
+collectMacroReferences(ParsedAST &AST) {
+ const auto &SM = AST.getSourceManager();
+ // FIXME: !!this is a hacky way to collect macro references.
+ std::vector<include_cleaner::SymbolReference> Macros;
+ auto &PP = AST.getPreprocessor();
+ for (const syntax::Token &Tok :
+ AST.getTokens().spelledTokens(SM.getMainFileID())) {
+ auto Macro = locateMacroAt(Tok, PP);
+ if (!Macro)
+ continue;
+ if (auto DefLoc = Macro->Info->getDefinitionLoc(); DefLoc.isValid())
+ Macros.push_back(
+ {Tok.location(),
+ include_cleaner::Macro{/*Name=*/PP.getIdentifierInfo(Tok.text(SM)),
+ DefLoc},
+ include_cleaner::RefType::Explicit});
+ }
+ return Macros;
+}
+
} // namespace
+include_cleaner::Includes
+convertIncludes(const SourceManager &SM,
+ const llvm::ArrayRef<Inclusion> MainFileIncludes) {
+ include_cleaner::Includes Includes;
+ for (const Inclusion &Inc : MainFileIncludes) {
+ include_cleaner::Include TransformedInc;
+ llvm::StringRef WrittenRef = llvm::StringRef(Inc.Written);
+ TransformedInc.Spelled = WrittenRef.trim("\"<>");
+ TransformedInc.HashLocation =
+ SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset);
+ TransformedInc.Line = Inc.HashLine + 1;
+ TransformedInc.Angled = WrittenRef.starts_with("<");
+ auto FE = SM.getFileManager().getFile(Inc.Resolved);
+ if (!FE)
+ continue;
+ TransformedInc.Resolved = *FE;
+ Includes.add(std::move(TransformedInc));
+ }
+ return Includes;
+}
+
std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
Position Pos) {
const SourceManager &SM = AST.getSourceManager();
@@ -1231,11 +1279,96 @@
DeclRelation::TemplatePattern | DeclRelation::Alias;
auto TargetDecls =
targetDecl(N->ASTNode, Relations, AST.getHeuristicResolver());
+
+ const IncludeStructure &Includes = AST.getIncludeStructure();
+ include_cleaner::Includes ConvertedIncludes =
+ convertIncludes(AST.getSourceManager(), Includes.MainFileIncludes);
+ include_cleaner::walkUsed(
+ AST.getLocalTopLevelDecls(),
+ collectMacroReferences(AST),
+ AST.getPragmaIncludes(),
+ AST.getSourceManager(),
+ [&](const include_cleaner::SymbolReference &Ref,
+ llvm::ArrayRef<include_cleaner::Header> Providers) {
+ // std::string SymbolName;
+ // switch (Ref.Target.kind()) {
+ // case include_cleaner::Symbol::Macro:
+ // break;
+ // case include_cleaner::Symbol::Declaration:
+ // SymbolName = static_cast<const NamedDecl &>(Ref.Target.declaration()).getNameAsString();
+ // if (SymbolName == "string") {
+ // llvm::errs() << "FOUND STRING" << "\n";
+ // llvm::errs() << "CUR LOCATION: " << "\n";
+ // llvm::errs() << SM.getDecomposedLoc(*CurLoc).second << "\n";
+ // llvm::errs() << "REF LOCATION: " << "\n";
+ // llvm::errs() << SM.getDecomposedLoc(Ref.RefLocation).second << "\n";
+ // }
+ // break;
+ // }
+ if (Ref.RefLocation != *CurLoc) {
+ return;
+ }
+ llvm::errs() << "GOT PAST THE GUARD" << "\n";
+ // the location under cursor corresponds to the current symbol reference
+ // need to find the position of the include
+ for (const auto &H : Providers) {
+ // switch (H.kind()) {
+ // case include_cleaner::Header::Physical:
+ // llvm::errs() << "It's a physical provider\n";
+ // if (auto HeaderID = Includes.getID(H.physical())) {
+ // llvm::errs() << "Physical provider: " << Includes.getRealPath(*HeaderID) << "\n";
+ // }
+ // break;
+ // case include_cleaner::Header::Standard:
+ // llvm::errs() << "It's a standard provider\n";
+ // for (auto HeaderID : Includes.StdlibHeaders.lookup(H.standard())) {
+ // llvm::errs() << "Standard provider: " << Includes.getRealPath(HeaderID) << "\n";
+ // }
+ // break;
+ // case include_cleaner::Header::Verbatim:
+ // llvm::errs() << "It's a verbatim provider\n";
+ // for (auto Inc : Includes.MainFileIncludes) {
+ // if (auto HeaderID = Inc.HeaderID) {
+ // llvm::errs() << "Verbatim provider: " <<
+ // Includes.getRealPath(static_cast<IncludeStructure::HeaderID>(*HeaderID)) << "\n";
+ // }
+ // }
+ // }
+ for (auto Inc : Includes.MainFileIncludes) {
+ if (Inc.Written == "<string>") {
+ llvm::errs() << "Included in main: " << Inc.Written << "\n";
+ }
+ }
+ for (auto *&Inc : ConvertedIncludes.match(H)) {
+ llvm::errs() << "Found match\n";
+ auto FID = SM.getFileID(SM.getFileLoc(Inc->HashLocation));
+ llvm::errs() << "FID: " << FID.getHashValue() << "\n";
+ auto Highlight = toHighlight(Inc->HashLocation, AST.getTokens());
+ llvm::errs() <<(Highlight.has_value() ? "Highlight" : "No highlight") << "\n";
+ // found the include in the includes list
+ // navigate to location
+ if (auto Highlight = toHighlight(Inc->HashLocation, AST.getTokens())) {
+ for (unsigned i = 1; i < 17; i++) {
+ if (auto HighlightNext = toHighlight(SM.getComposedLoc(SM.getMainFileID(),
+ SM.getDecomposedLoc(Inc->HashLocation).second + i), AST.getTokens())) {
+ Result.push_back(*HighlightNext);
+ }
+ }
+ llvm::errs() << "COULD BUILD THE HIGHLIGHT FOR " << Inc->Spelled << "\n";
+ Result.push_back(*Highlight);
+ } else {
+ llvm::errs() << "COULD NOT BUILD THE HIGHLIGHT FOR " << Inc->Spelled << "\n";
+ }
+ }
+ }
+ });
+
if (!TargetDecls.empty()) {
// FIXME: we may get multiple DocumentHighlights with the same location
// and different kinds, deduplicate them.
for (const auto &Ref : findRefs(TargetDecls, AST, /*PerToken=*/true))
Result.push_back(toHighlight(Ref, SM));
+ // TODO (bakalova) include-cleaner analysis here
return true;
}
auto ControlFlow = relatedControlFlow(*N);
@@ -1312,6 +1445,90 @@
}
} // namespace
+std::vector<CodeLens> findCodeLens(ParsedAST &AST) {
+ // TODO(bakalova) find ranges
+ // TODO(bakalova) find used symbols
+
+ std::vector<CodeLens> Result;
+ std::vector<Inclusion> Includes = AST.getIncludeStructure().MainFileIncludes;
+
+ IncludeSpelling S;
+ S.spelling = "string";
+ for (auto Inclusion : Includes) {
+ std::set<std::string> UsedSymbols;
+ walkUsed(AST.getLocalTopLevelDecls(),
+ collectMacroReferences(AST),
+ AST.getPragmaIncludes(),
+ AST.getSourceManager(),
+ [&](const include_cleaner::SymbolReference &Ref,
+ llvm::ArrayRef<include_cleaner::Header> Providers) {
+
+ std::string Name;
+ switch(Ref.Target.kind()) {
+ case include_cleaner::Symbol::Declaration:
+ Name = cast<NamedDecl>(Ref.Target.declaration())
+ .getDeclName()
+ .getAsString();
+ break;
+ case include_cleaner::Symbol::Macro:
+ Name = Ref.Target.macro().Name->getName();
+ break;
+ }
+ for (const include_cleaner::Header &H : Providers) {
+ switch (H.kind()) {
+ case include_cleaner::Header::Physical:
+ if (H.physical()->tryGetRealPathName().contains(
+ llvm::StringRef(Inclusion.Written).trim("\"<>"))) {
+ UsedSymbols.insert(Name);
+ }
+ break;
+ case include_cleaner::Header::Standard:
+ if (Inclusion.Written == H.standard().name()) {
+ UsedSymbols.insert(Name);
+ }
+ break;
+ // TODO(bakalova) does the verbatim thing include quotes or not?
+ case include_cleaner::Header::Verbatim:
+ if (Inclusion.Written == H.verbatim()) {
+ UsedSymbols.insert(Name);
+ }
+ break;
+ }
+ }
+ });
+
+ CodeLens Lens;
+ Lens.range = clangd::Range{Position{Inclusion.HashLine, 0}, Position{Inclusion.HashLine, 0}};
+ Command cmd;
+
+ std::vector<std::string> UsedSymbolsDeduped;
+ for (auto Sym : UsedSymbols) {
+ UsedSymbolsDeduped.push_back(Sym);
+ }
+
+ for (unsigned i = 0; i < 4 && i < UsedSymbolsDeduped.size(); i++) {
+ std::string Name = UsedSymbolsDeduped[i];
+ cmd.title += Name;
+ cmd.title += " | ";
+ }
+ if (UsedSymbols.size() >= 5) {
+ cmd.title += UsedSymbolsDeduped[4];
+ cmd.title += " | ...";
+ }
+
+ cmd.command = "HelloWorld";
+ cmd.argument = toJSON(S);
+ Lens.command = cmd;
+ Result.push_back(Lens);
+ }
+
+
+ for (auto CodeLens : Result) {
+ llvm::errs() << "CODE LENS: " << CodeLens << "\n";
+ }
+ return Result;
+}
+
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
const SymbolIndex *Index, bool AddContext) {
ReferencesResult Results;
Index: clang-tools-extra/clangd/Protocol.h
===================================================================
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -976,6 +976,12 @@
bool fromJSON(const llvm::json::Value &, WorkspaceEdit &, llvm::json::Path);
llvm::json::Value toJSON(const WorkspaceEdit &WE);
+struct IncludeSpelling {
+ std::string spelling;
+};
+bool fromJSON(const llvm::json::Value &, IncludeSpelling &, llvm::json::Path);
+llvm::json::Value toJSON(const IncludeSpelling &IS);
+
/// Arguments for the 'applyTweak' command. The server sends these commands as a
/// response to the textDocument/codeAction request. The client can later send a
/// command back to the server if the user requests to execute a particular code
@@ -1876,6 +1882,19 @@
llvm::json::Value toJSON(const ASTNode &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &);
+struct CodeLensParams {
+ TextDocumentIdentifier textDocument;
+};
+bool fromJSON(const llvm::json::Value &, CodeLensParams &,
+ llvm::json::Path);
+
+struct CodeLens {
+ Range range;
+ Command command;
+};
+llvm::json::Value toJSON(const CodeLens &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CodeLens &);
+
} // namespace clangd
} // namespace clang
Index: clang-tools-extra/clangd/Protocol.cpp
===================================================================
--- clang-tools-extra/clangd/Protocol.cpp
+++ clang-tools-extra/clangd/Protocol.cpp
@@ -535,6 +535,17 @@
return O && O.map("textDocument", R.textDocument);
}
+bool fromJSON(const llvm::json::Value &Params, CodeLensParams &R,
+ llvm::json::Path P) {
+ llvm::json::ObjectMapper O(Params, P);
+ return O && O.map("textDocument", R.textDocument);
+}
+
+bool fromJSON(const llvm::json::Value &Params, IncludeSpelling &R, llvm::json::Path P) {
+ llvm::json::ObjectMapper O(Params, P);
+ return O && O.map("spelling", R.spelling);
+}
+
bool fromJSON(const llvm::json::Value &Params, DidSaveTextDocumentParams &R,
llvm::json::Path P) {
llvm::json::ObjectMapper O(Params, P);
@@ -613,6 +624,22 @@
};
}
+llvm::json::Value toJSON(const IncludeSpelling &IS) {
+ return llvm::json::Object{
+ {"spelling", IS.spelling}
+ };
+}
+
+llvm::json::Value toJSON(const CodeLens &CL) {
+ return llvm::json::Object {
+ {"range", CL.range},
+ {"command", CL.command}
+ };
+}
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const CodeLens &CL) {
+ return OS << "Code lens: " << CL.range.start << '-' << CL.range.end;
+}
+
llvm::json::Value toJSON(DiagnosticTag Tag) { return static_cast<int>(Tag); }
llvm::json::Value toJSON(const CodeDescription &D) {
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -15,6 +15,8 @@
#include "ParsedAST.h"
#include "Selection.h"
#include "SourceCode.h"
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Types.h"
#include "index/SymbolCollector.h"
#include "support/Markup.h"
#include "clang/AST/ASTContext.h"
@@ -1084,8 +1086,67 @@
return Candidates.front();
}
+std::vector<include_cleaner::SymbolReference>
+collectMacroReferences(ParsedAST &AST) {
+ const auto &SM = AST.getSourceManager();
+ // FIXME: !!this is a hacky way to collect macro references.
+ std::vector<include_cleaner::SymbolReference> Macros;
+ auto &PP = AST.getPreprocessor();
+ for (const syntax::Token &Tok :
+ AST.getTokens().spelledTokens(SM.getMainFileID())) {
+ auto Macro = locateMacroAt(Tok, PP);
+ if (!Macro)
+ continue;
+ if (auto DefLoc = Macro->Info->getDefinitionLoc(); DefLoc.isValid())
+ Macros.push_back(
+ {Tok.location(),
+ include_cleaner::Macro{/*Name=*/PP.getIdentifierInfo(Tok.text(SM)),
+ DefLoc},
+ include_cleaner::RefType::Explicit});
+ }
+ return Macros;
+}
+
} // namespace
+void maybeAddHeaderProvider(ParsedAST &AST, HoverInfo &HI, SourceLocation CurLoc) {
+ llvm::errs() << "CALLED ADD HEADER PROVIDER\n";
+ include_cleaner::walkUsed(AST.getLocalTopLevelDecls(),
+ collectMacroReferences(AST),
+ AST.getPragmaIncludes(),
+ AST.getSourceManager(),
+ [&](const include_cleaner::SymbolReference &Ref,
+ llvm::ArrayRef<include_cleaner::Header> Providers) {
+ if (Ref.RefLocation != CurLoc) {
+ return;
+ }
+ StringRef ProviderName;
+ if (!Providers.empty()) {
+ include_cleaner::Header FirstProvider = Providers[0];
+ // TODO(bakalova) switch on provider type
+ switch(FirstProvider.kind()) {
+ case include_cleaner::Header::Physical:
+ ProviderName = FirstProvider.physical()->tryGetRealPathName();
+ llvm::errs() << "PHYSICAL PROVIDER: " << ProviderName << "\n";
+ break;
+ case include_cleaner::Header::Standard:
+ ProviderName = FirstProvider.standard().name();
+ llvm::errs() << "STANDARD PROVIDER: " << ProviderName << "\n";
+ break;
+ case include_cleaner::Header::Verbatim:
+ ProviderName = FirstProvider.verbatim();
+ llvm::errs() << "VERBATIM PROVIDER: " << ProviderName << "\n";
+ break;
+ }
+ HI.Documentation += "\n\n";
+ HI.Documentation += "Provided by `";
+ HI.Documentation += ProviderName;
+ HI.Documentation += "`.";
+ llvm::errs() << "DOC: " << HI.Documentation << "\n";
+ }
+ });
+}
+
std::optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
const format::FormatStyle &Style,
const SymbolIndex *Index) {
@@ -1168,6 +1229,7 @@
if (!HI->Value)
HI->Value = printExprValue(N, AST.getASTContext());
maybeAddCalleeArgInfo(N, *HI, PP);
+ maybeAddHeaderProvider(AST, *HI, *CurLoc);
} else if (const Expr *E = N->ASTNode.get<Expr>()) {
HI = getHoverContents(N, E, AST, PP, Index);
} else if (const Attr *A = N->ASTNode.get<Attr>()) {
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -305,6 +305,8 @@
void findReferences(PathRef File, Position Pos, uint32_t Limit,
bool AddContainer, Callback<ReferencesResult> CB);
+ void findCodeLens(PathRef File, Callback<std::vector<CodeLens>> CB);
+
/// Run formatting for the \p File with content \p Code.
/// If \p Rng is non-null, formats only that region.
void formatFile(PathRef File, std::optional<Range> Rng,
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -911,6 +911,17 @@
WorkScheduler->runWithAST("References", File, std::move(Action));
}
+void ClangdServer::findCodeLens(PathRef File, Callback<std::vector<CodeLens>> CB) {
+ auto Action = [CB = std::move(CB)](llvm::Expected<InputsAndAST> InpAST) mutable {
+ if (!InpAST)
+ return CB(InpAST.takeError());
+
+ CB(clangd::findCodeLens(InpAST->AST));
+ };
+
+ WorkScheduler->runWithAST("CodeLens", File, std::move(Action));
+}
+
void ClangdServer::symbolInfo(PathRef File, Position Pos,
Callback<std::vector<SymbolDetails>> CB) {
auto Action =
Index: clang-tools-extra/clangd/ClangdLSPServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.h
+++ clang-tools-extra/clangd/ClangdLSPServer.h
@@ -173,6 +173,9 @@
void onCommandApplyEdit(const WorkspaceEdit &, Callback<llvm::json::Value>);
void onCommandApplyTweak(const TweakArgs &, Callback<llvm::json::Value>);
+ void onCodeLens(const CodeLensParams &Params, Callback<std::vector<CodeLens>> Reply);
+ void onCommandShowUsedSymbols(const IncludeSpelling &Spelling, Callback<llvm::json::Value> Reply);
+
/// Outgoing LSP calls.
LSPBinder::OutgoingMethod<ApplyWorkspaceEditParams,
ApplyWorkspaceEditResponse>
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -71,6 +71,7 @@
const llvm::StringLiteral ApplyFixCommand = "clangd.applyFix";
const llvm::StringLiteral ApplyTweakCommand = "clangd.applyTweak";
+const llvm::StringLiteral ApplyShowUsedSymbols = "HelloWorld";
/// Transforms a tweak into a code action that would apply it if executed.
/// EXPECTS: T.prepare() was called and returned true.
@@ -586,6 +587,7 @@
{"clangdInlayHintsProvider", true},
{"inlayHintProvider", true},
{"foldingRangeProvider", true},
+ {"codeLensProvider", true},
};
{
@@ -736,6 +738,14 @@
applyEdit(WE, "Fix applied.", std::move(Reply));
}
+void ClangdLSPServer::onCommandShowUsedSymbols(const IncludeSpelling &Spelling, Callback<llvm::json::Value> Reply) {
+ llvm::errs() << "ONCOMMAND SHOW USED SYMBOLS TRIGGERED\n";
+ llvm::json::Value Response = llvm::json::Object{
+ {"response", "Hello to you as well!!!"}
+ };
+ return Reply(Response);
+}
+
void ClangdLSPServer::onCommandApplyTweak(const TweakArgs &Args,
Callback<llvm::json::Value> Reply) {
auto Action = [this, Reply = std::move(Reply)](
@@ -1399,6 +1409,12 @@
});
}
+void ClangdLSPServer::onCodeLens(const CodeLensParams &Params,
+ Callback<std::vector<CodeLens>> Reply) {
+ llvm::errs() << "TRIGGERED CODE LENS: " << Params.textDocument.uri.file() << "\n";
+ Server->findCodeLens(Params.textDocument.uri.file(), std::move(Reply));
+}
+
void ClangdLSPServer::onGoToType(const TextDocumentPositionParams &Params,
Callback<std::vector<Location>> Reply) {
Server->findType(
@@ -1589,6 +1605,7 @@
Bind.method("textDocument/typeDefinition", this, &ClangdLSPServer::onGoToType);
Bind.method("textDocument/implementation", this, &ClangdLSPServer::onGoToImplementation);
Bind.method("textDocument/references", this, &ClangdLSPServer::onReference);
+ Bind.method("textDocument/codeLens", this, &ClangdLSPServer::onCodeLens);
Bind.method("textDocument/switchSourceHeader", this, &ClangdLSPServer::onSwitchSourceHeader);
Bind.method("textDocument/prepareRename", this, &ClangdLSPServer::onPrepareRename);
Bind.method("textDocument/rename", this, &ClangdLSPServer::onRename);
@@ -1622,6 +1639,7 @@
Bind.method("textDocument/foldingRange", this, &ClangdLSPServer::onFoldingRange);
Bind.command(ApplyFixCommand, this, &ClangdLSPServer::onCommandApplyEdit);
Bind.command(ApplyTweakCommand, this, &ClangdLSPServer::onCommandApplyTweak);
+ Bind.command(ApplyShowUsedSymbols, this, &ClangdLSPServer::onCommandShowUsedSymbols);
ApplyWorkspaceEdit = Bind.outgoingMethod("workspace/applyEdit");
PublishDiagnostics = Bind.outgoingNotification("textDocument/publishDiagnostics");
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits