2017-05-16 17:38:59 +08:00
|
|
|
//===--- ClangdServer.h - Main clangd server code ----------------*- C++-*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-05-16 17:38:59 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H
|
|
|
|
|
2019-01-22 17:39:05 +08:00
|
|
|
#include "../clang-tidy/ClangTidyOptions.h"
|
2017-12-15 05:22:03 +08:00
|
|
|
#include "CodeComplete.h"
|
2020-07-03 05:09:25 +08:00
|
|
|
#include "ConfigProvider.h"
|
2017-05-16 17:38:59 +08:00
|
|
|
#include "GlobalCompilationDatabase.h"
|
[clangd] Untangle Hover from XRefs, move into own file.
Summary:
This is mostly mechanical, with a few exceptions:
- getDeducedType moved into AST.h where it belongs. It now takes
ASTContext instead of ParsedAST, and avoids using the preprocessor.
- hover now uses SelectionTree directly rather than via
getDeclAtPosition helper
- hover on 'auto' used to find the decl that contained the 'auto' and
use that to set Kind and documentation for the hover result.
Now we use targetDecl() to find the decl matching the deduced type instead.
This changes tests, e.g. 'variable' -> class for auto on lambdas.
I think this is better, but the motivation was to avoid depending on
the internals of DeducedTypeVisitor. This functionality is removed
from the visitor.
Reviewers: kadircet
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70357
2019-11-17 00:00:19 +08:00
|
|
|
#include "Hover.h"
|
2017-12-15 05:22:03 +08:00
|
|
|
#include "Protocol.h"
|
2019-06-27 23:13:03 +08:00
|
|
|
#include "SemanticHighlighting.h"
|
2018-01-31 16:51:16 +08:00
|
|
|
#include "TUScheduler.h"
|
[clangd] Implement textDocument/declaration from LSP 3.14
Summary:
LSP now reflects the declaration/definition distinction.
Language server changes:
- textDocument/definition now returns a definition if one is found, otherwise
the declaration. It no longer returns declaration + definition if they are
distinct.
- textDocument/declaration returns the best declaration we can find.
- For macros, the active macro definition is returned for both methods.
- For include directive, the top of the target file is returned for both.
There doesn't appear to be a discovery mechanism (we can't return everything to
clients that only know about definition), so this changes existing behavior.
In practice, it should greatly reduce the fraction of the time we need to show
the user a menu of options.
C++ API changes:
- findDefinitions is replaced by locateSymbolAt, which returns a
vector<LocatedSymbol> - one for each symbol under the cursor.
- this contains the preferred declaration, the definition (if found), and
the symbol name
This API enables some potentially-neat extensions, like swapping between decl
and def, and exposing the symbol name to the UI in the case of multiple symbols.
Reviewers: hokein
Subscribers: ilya-biryukov, javed.absar, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D57388
llvm-svn: 352864
2019-02-01 19:26:13 +08:00
|
|
|
#include "XRefs.h"
|
[clangd] Enable auto-index behind a flag.
Summary:
Ownership and configuration:
The auto-index (background index) is maintained by ClangdServer, like Dynamic.
(This means ClangdServer will be able to enqueue preamble indexing in future).
For now it's enabled by a simple boolean flag in ClangdServer::Options, but
we probably want to eventually allow injecting the storage strategy.
New 'sync' command:
In order to meaningfully test the integration (not just unit-test components)
we need a way for tests to ensure the asynchronous index reads/writes occur
before a certain point.
Because these tests and assertions are few, I think exposing an explicit "sync"
command for use in tests is simpler than allowing threading to be completely
disabled in the background index (as we do for TUScheduler).
Bugs:
I fixed a couple of trivial bugs I found while testing, but there's one I can't.
JSONCompilationDatabase::getAllFiles() may return relative paths, and currently
we trigger an assertion that assumes they are absolute.
There's no efficient way to resolve them (you have to retrieve the corresponding
command and then resolve against its directory property). In general I think
this behavior is broken and we should fix it in JSONCompilationDatabase and
require CompilationDatabase::getAllFiles() to be absolute.
Reviewers: kadircet
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D54894
llvm-svn: 347567
2018-11-27 00:00:11 +08:00
|
|
|
#include "index/Background.h"
|
2017-12-20 02:00:37 +08:00
|
|
|
#include "index/FileIndex.h"
|
[clangd] Speculative code completion index request before Sema is run.
Summary:
For index-based code completion, send an asynchronous speculative index
request, based on the index request for the last code completion on the same
file and the filter text typed before the cursor, before sema code completion
is invoked. This can reduce the code completion latency (by roughly latency of
sema code completion) if the speculative request is the same as the one
generated for the ongoing code completion from sema. As a sequence of code
completions often have the same scopes and proximity paths etc, this should be
effective for a number of code completions.
Trace with speculative index request:{F6997544}
Reviewers: hokein, ilya-biryukov
Reviewed By: ilya-biryukov
Subscribers: javed.absar, jfb, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D50962
llvm-svn: 340604
2018-08-24 19:23:56 +08:00
|
|
|
#include "index/Index.h"
|
2019-10-23 20:40:20 +08:00
|
|
|
#include "refactor/Rename.h"
|
[clangd] Interfaces for writing code tweaks
Summary:
The code tweaks are an implementation of mini-refactorings exposed
via the LSP code actions. They run in two stages:
- Stage 1. Decides whether the action is available to the user and
collects all the information required to finish the action.
Should be cheap, since this will run over all the actions known to
clangd on each textDocument/codeAction request from the client.
- Stage 2. Uses information from stage 1 to produce the actual edits
that the code action should perform. This stage can be expensive and
will only run if the user chooses to perform the specified action in
the UI.
One unfortunate consequence of this change is increased latency of
processing the textDocument/codeAction requests, which now wait for an
AST. However, we cannot avoid this with what we have available in the LSP
today.
Reviewers: kadircet, ioeric, hokein, sammccall
Reviewed By: sammccall
Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D56267
llvm-svn: 352494
2019-01-29 22:17:36 +08:00
|
|
|
#include "refactor/Tweak.h"
|
[clangd] Move non-clang base pieces into separate support/ lib. NFCI
Summary:
This enforces layering, reduces a sprawling clangd/ directory, and makes life
easier for embedders.
Reviewers: kbobyrev
Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, jfb, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D79014
2020-04-28 23:49:17 +08:00
|
|
|
#include "support/Cancellation.h"
|
|
|
|
#include "support/Function.h"
|
2020-06-17 17:53:32 +08:00
|
|
|
#include "support/ThreadsafeFS.h"
|
2017-05-16 17:38:59 +08:00
|
|
|
#include "clang/Tooling/CompilationDatabase.h"
|
|
|
|
#include "clang/Tooling/Core/Replacement.h"
|
[clangd] Interfaces for writing code tweaks
Summary:
The code tweaks are an implementation of mini-refactorings exposed
via the LSP code actions. They run in two stages:
- Stage 1. Decides whether the action is available to the user and
collects all the information required to finish the action.
Should be cheap, since this will run over all the actions known to
clangd on each textDocument/codeAction request from the client.
- Stage 2. Uses information from stage 1 to produce the actual edits
that the code action should perform. This stage can be expensive and
will only run if the user chooses to perform the specified action in
the UI.
One unfortunate consequence of this change is increased latency of
processing the textDocument/codeAction requests, which now wait for an
AST. However, we cannot avoid this with what we have available in the LSP
today.
Reviewers: kadircet, ioeric, hokein, sammccall
Reviewed By: sammccall
Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D56267
llvm-svn: 352494
2019-01-29 22:17:36 +08:00
|
|
|
#include "llvm/ADT/FunctionExtras.h"
|
2017-05-16 17:38:59 +08:00
|
|
|
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
|
|
|
#include "llvm/ADT/Optional.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
2017-05-23 21:42:59 +08:00
|
|
|
#include <functional>
|
2018-02-09 18:17:23 +08:00
|
|
|
#include <future>
|
2017-05-16 17:38:59 +08:00
|
|
|
#include <string>
|
2017-05-30 23:11:02 +08:00
|
|
|
#include <type_traits>
|
2017-05-16 17:38:59 +08:00
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
|
2019-05-21 01:30:46 +08:00
|
|
|
/// When set, used by ClangdServer to get clang-tidy options for each particular
|
|
|
|
/// file. Must be thread-safe. We use this instead of ClangTidyOptionsProvider
|
|
|
|
/// to allow reading tidy configs from the VFS used for parsing.
|
|
|
|
using ClangTidyOptionsBuilder = std::function<tidy::ClangTidyOptions(
|
|
|
|
llvm::vfs::FileSystem &, llvm::StringRef /*File*/)>;
|
|
|
|
|
2018-09-13 20:58:36 +08:00
|
|
|
/// Manages a collection of source files and derived data (ASTs, indexes),
|
|
|
|
/// and provides language-aware features such as code completion.
|
|
|
|
///
|
|
|
|
/// The primary client is ClangdLSPServer which exposes these features via
|
|
|
|
/// the Language Server protocol. ClangdServer may also be embedded directly,
|
|
|
|
/// though its API is not stable over time.
|
|
|
|
///
|
|
|
|
/// ClangdServer should be used from a single thread. Many potentially-slow
|
|
|
|
/// operations have asynchronous APIs and deliver their results on another
|
|
|
|
/// thread.
|
|
|
|
/// Such operations support cancellation: if the caller sets up a cancelable
|
|
|
|
/// context, many operations will notice cancellation and fail early.
|
|
|
|
/// (ClangdLSPServer uses this to implement $/cancelRequest).
|
2017-05-16 17:38:59 +08:00
|
|
|
class ClangdServer {
|
|
|
|
public:
|
2020-01-24 21:08:56 +08:00
|
|
|
/// Interface with hooks for users of ClangdServer to be notified of events.
|
|
|
|
class Callbacks {
|
|
|
|
public:
|
|
|
|
virtual ~Callbacks() = default;
|
|
|
|
|
|
|
|
/// Called by ClangdServer when \p Diagnostics for \p File are ready.
|
|
|
|
/// May be called concurrently for separate files, not for a single file.
|
[clangd] Track document versions, include them with diags, enhance logs
Summary:
This ties to an LSP feature (diagnostic versioning) but really a lot
of the value is in being able to log what's happening with file versions
and queues more descriptively and clearly.
As such it's fairly invasive, for a logging patch :-\
Key decisions:
- at the LSP layer, we don't reqire the client to provide versions (LSP
makes it mandatory but we never enforced it). If not provided,
versions start at 0 and increment. DraftStore handles this.
- don't propagate magically using contexts, but rather manually:
addDocument -> ParseInputs -> (ParsedAST, Preamble, various callbacks)
Context-propagation would hide the versions from ClangdServer, which
would make producing good log messages hard
- within ClangdServer, treat versions as opaque and unordered.
std::string is a convenient type for this, and allows richer versions
for embedders. They're "mandatory" but "null" is a reasonable default.
Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75582
2020-03-04 07:33:29 +08:00
|
|
|
virtual void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
|
2020-01-24 21:08:56 +08:00
|
|
|
std::vector<Diag> Diagnostics) {}
|
|
|
|
/// Called whenever the file status is updated.
|
|
|
|
/// May be called concurrently for separate files, not for a single file.
|
2020-01-24 23:12:00 +08:00
|
|
|
virtual void onFileUpdated(PathRef File, const TUStatus &Status) {}
|
2020-01-24 21:08:56 +08:00
|
|
|
|
|
|
|
/// Called by ClangdServer when some \p Highlightings for \p File are ready.
|
|
|
|
/// May be called concurrently for separate files, not for a single file.
|
|
|
|
virtual void
|
[clangd] Track document versions, include them with diags, enhance logs
Summary:
This ties to an LSP feature (diagnostic versioning) but really a lot
of the value is in being able to log what's happening with file versions
and queues more descriptively and clearly.
As such it's fairly invasive, for a logging patch :-\
Key decisions:
- at the LSP layer, we don't reqire the client to provide versions (LSP
makes it mandatory but we never enforced it). If not provided,
versions start at 0 and increment. DraftStore handles this.
- don't propagate magically using contexts, but rather manually:
addDocument -> ParseInputs -> (ParsedAST, Preamble, various callbacks)
Context-propagation would hide the versions from ClangdServer, which
would make producing good log messages hard
- within ClangdServer, treat versions as opaque and unordered.
std::string is a convenient type for this, and allows richer versions
for embedders. They're "mandatory" but "null" is a reasonable default.
Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75582
2020-03-04 07:33:29 +08:00
|
|
|
onHighlightingsReady(PathRef File, llvm::StringRef Version,
|
2020-01-24 21:08:56 +08:00
|
|
|
std::vector<HighlightingToken> Highlightings) {}
|
|
|
|
|
|
|
|
/// Called when background indexing tasks are enqueued/started/completed.
|
|
|
|
/// Not called concurrently.
|
|
|
|
virtual void
|
|
|
|
onBackgroundIndexProgress(const BackgroundQueue::Stats &Stats) {}
|
|
|
|
};
|
|
|
|
|
2018-03-06 01:28:54 +08:00
|
|
|
struct Options {
|
|
|
|
/// To process requests asynchronously, ClangdServer spawns worker threads.
|
2018-09-13 20:58:36 +08:00
|
|
|
/// If this is zero, no threads are spawned. All work is done on the calling
|
|
|
|
/// thread, and callbacks are invoked before "async" functions return.
|
2018-03-06 01:28:54 +08:00
|
|
|
unsigned AsyncThreadsCount = getDefaultAsyncThreadsCount();
|
|
|
|
|
[clangd] Keep only a limited number of idle ASTs in memory
Summary:
After this commit, clangd will only keep the last 3 accessed ASTs in
memory. Preambles for each of the opened files are still kept in
memory to make completion and AST rebuilds fast.
AST rebuilds are usually fast enough, but having the last ASTs in
memory still considerably improves latency of operations like
findDefinition and documeneHighlight, which are often sent multiple
times a second when moving around the code. So keeping some of the last
accessed ASTs in memory seems like a reasonable tradeoff.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: malaperle, arphaman, klimek, javed.absar, ioeric, MaskRay, jkorous, cfe-commits
Differential Revision: https://reviews.llvm.org/D47063
llvm-svn: 333737
2018-06-01 18:08:43 +08:00
|
|
|
/// AST caching policy. The default is to keep up to 3 ASTs in memory.
|
|
|
|
ASTRetentionPolicy RetentionPolicy;
|
|
|
|
|
2018-03-06 01:28:54 +08:00
|
|
|
/// Cached preambles are potentially large. If false, store them on disk.
|
|
|
|
bool StorePreamblesInMemory = true;
|
2020-04-08 03:18:00 +08:00
|
|
|
/// Reuse even stale preambles, and rebuild them in the background.
|
|
|
|
/// This improves latency at the cost of accuracy.
|
2020-07-07 18:30:58 +08:00
|
|
|
bool AsyncPreambleBuilds = true;
|
2018-03-06 01:28:54 +08:00
|
|
|
|
|
|
|
/// If true, ClangdServer builds a dynamic in-memory index for symbols in
|
|
|
|
/// opened files and uses the index to augment code completion results.
|
|
|
|
bool BuildDynamicSymbolIndex = false;
|
2018-10-16 16:53:52 +08:00
|
|
|
/// Use a heavier and faster in-memory index implementation.
|
2019-06-11 04:38:16 +08:00
|
|
|
bool HeavyweightDynamicSymbolIndex = true;
|
[clangd] Enable auto-index behind a flag.
Summary:
Ownership and configuration:
The auto-index (background index) is maintained by ClangdServer, like Dynamic.
(This means ClangdServer will be able to enqueue preamble indexing in future).
For now it's enabled by a simple boolean flag in ClangdServer::Options, but
we probably want to eventually allow injecting the storage strategy.
New 'sync' command:
In order to meaningfully test the integration (not just unit-test components)
we need a way for tests to ensure the asynchronous index reads/writes occur
before a certain point.
Because these tests and assertions are few, I think exposing an explicit "sync"
command for use in tests is simpler than allowing threading to be completely
disabled in the background index (as we do for TUScheduler).
Bugs:
I fixed a couple of trivial bugs I found while testing, but there's one I can't.
JSONCompilationDatabase::getAllFiles() may return relative paths, and currently
we trigger an assertion that assumes they are absolute.
There's no efficient way to resolve them (you have to retrieve the corresponding
command and then resolve against its directory property). In general I think
this behavior is broken and we should fix it in JSONCompilationDatabase and
require CompilationDatabase::getAllFiles() to be absolute.
Reviewers: kadircet
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D54894
llvm-svn: 347567
2018-11-27 00:00:11 +08:00
|
|
|
/// If true, ClangdServer automatically indexes files in the current project
|
|
|
|
/// on background threads. The index is stored in the project root.
|
|
|
|
bool BackgroundIndex = false;
|
2018-03-06 01:28:54 +08:00
|
|
|
|
2020-08-17 06:22:04 +08:00
|
|
|
/// Store refs to main-file symbols in the index.
|
|
|
|
bool CollectMainFileRefs = false;
|
|
|
|
|
2018-03-06 01:28:54 +08:00
|
|
|
/// If set, use this index to augment code completion results.
|
|
|
|
SymbolIndex *StaticIndex = nullptr;
|
|
|
|
|
2020-07-03 05:09:25 +08:00
|
|
|
/// If set, queried to obtain the configuration to handle each request.
|
|
|
|
config::Provider *ConfigProvider = nullptr;
|
|
|
|
|
2019-05-21 01:30:46 +08:00
|
|
|
/// If set, enable clang-tidy in clangd and use to it get clang-tidy
|
2019-01-22 17:39:05 +08:00
|
|
|
/// configurations for a particular file.
|
|
|
|
/// Clangd supports only a small subset of ClangTidyOptions, these options
|
|
|
|
/// (Checks, CheckOptions) are about which clang-tidy checks will be
|
|
|
|
/// enabled.
|
2019-05-21 01:30:46 +08:00
|
|
|
ClangTidyOptionsBuilder GetClangTidyOptions;
|
2019-01-22 17:39:05 +08:00
|
|
|
|
2020-03-31 22:09:49 +08:00
|
|
|
/// If true, turn on the `-frecovery-ast` clang flag.
|
2020-06-12 22:05:38 +08:00
|
|
|
bool BuildRecoveryAST = true;
|
2020-03-31 22:09:49 +08:00
|
|
|
|
2020-05-19 21:21:50 +08:00
|
|
|
/// If true, turn on the `-frecovery-ast-type` clang flag.
|
2020-08-26 22:46:24 +08:00
|
|
|
bool PreserveRecoveryASTType = true;
|
2020-05-19 21:21:50 +08:00
|
|
|
|
2018-10-19 23:42:23 +08:00
|
|
|
/// Clangd's workspace root. Relevant for "workspace" operations not bound
|
|
|
|
/// to a particular file.
|
|
|
|
/// FIXME: If not set, should use the current working directory.
|
|
|
|
llvm::Optional<std::string> WorkspaceRoot;
|
|
|
|
|
2018-03-06 01:28:54 +08:00
|
|
|
/// The resource directory is used to find internal headers, overriding
|
|
|
|
/// defaults and -resource-dir compiler flag).
|
|
|
|
/// If None, ClangdServer calls CompilerInvocation::GetResourcePath() to
|
|
|
|
/// obtain the standard resource directory.
|
[clangd] Enforce rules around "initialize" request, and create ClangdServer lazily.
Summary:
LSP is a slightly awkward map to C++ object lifetimes: the initialize request
is part of the protocol and provides information that doesn't change over the
lifetime of the server.
Until now, we handled this by initializing ClangdServer and ClangdLSPServer
right away, and making anything that can be set in the "initialize" request
mutable.
With this patch, we create ClangdLSPServer immediately, but defer creating
ClangdServer until "initialize". This opens the door to passing the relevant
initialize params in the constructor and storing them immutably.
(That change isn't actually done in this patch).
To make this safe, we have the MessageDispatcher enforce that the "initialize"
method is called before any other (as required by LSP). That way each method
handler can assume Server is initialized, as today.
As usual, while implementing this I found places where our test cases violated
the protocol.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D53398
llvm-svn: 344741
2018-10-18 22:41:50 +08:00
|
|
|
llvm::Optional<std::string> ResourceDir = llvm::None;
|
2018-03-06 01:28:54 +08:00
|
|
|
|
|
|
|
/// Time to wait after a new file version before computing diagnostics.
|
2020-02-04 19:47:05 +08:00
|
|
|
DebouncePolicy UpdateDebounce = DebouncePolicy{
|
|
|
|
/*Min=*/std::chrono::milliseconds(50),
|
|
|
|
/*Max=*/std::chrono::milliseconds(500),
|
|
|
|
/*RebuildRatio=*/1,
|
|
|
|
};
|
2019-01-28 22:01:55 +08:00
|
|
|
|
|
|
|
bool SuggestMissingIncludes = false;
|
2019-06-18 21:37:54 +08:00
|
|
|
|
2019-06-26 15:45:27 +08:00
|
|
|
/// Clangd will execute compiler drivers matching one of these globs to
|
|
|
|
/// fetch system include path.
|
|
|
|
std::vector<std::string> QueryDriverGlobs;
|
2019-06-27 23:13:03 +08:00
|
|
|
|
2020-04-01 18:02:28 +08:00
|
|
|
/// Enable notification-based semantic highlighting.
|
2020-03-24 07:31:14 +08:00
|
|
|
bool TheiaSemanticHighlighting = false;
|
2019-07-02 00:55:29 +08:00
|
|
|
|
[clangd] Implement textDocument/foldingRange
Summary:
This patch introduces basic textDocument/foldingRange support. It relies on
textDocument/documentSymbols to collect all symbols and uses takes ranges
to create folds.
The next steps for textDocument/foldingRange support would be:
* Implementing FoldingRangeClientCapabilities and respecting respect client
preferences
* Specifying folding range kind
* Migrating from DocumentSymbol implementation to custom RecursiveASTVisitor flow that will allow more flexibility
* Supporting more folding range types: comments, PP conditional regions, includes and other code regions (e.g. public/private/protected sections of classes, control flow statement bodies)
Tested: (Neo)Vim (coc-clangd) and VSCode.
Related issue: https://github.com/clangd/clangd/issues/310
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: nridge, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82436
2020-07-14 15:28:38 +08:00
|
|
|
/// Enable preview of FoldingRanges feature.
|
|
|
|
bool FoldingRanges = false;
|
|
|
|
|
2019-07-12 16:50:20 +08:00
|
|
|
/// Returns true if the tweak should be enabled.
|
|
|
|
std::function<bool(const Tweak &)> TweakFilter = [](const Tweak &T) {
|
|
|
|
return !T.hidden(); // only enable non-hidden tweaks.
|
|
|
|
};
|
2020-02-03 18:18:13 +08:00
|
|
|
|
|
|
|
explicit operator TUScheduler::Options() const;
|
2018-03-06 01:28:54 +08:00
|
|
|
};
|
|
|
|
// Sensible default options for use in tests.
|
|
|
|
// Features like indexing must be enabled if desired.
|
|
|
|
static Options optsForTest();
|
|
|
|
|
2017-08-22 17:16:46 +08:00
|
|
|
/// Creates a new ClangdServer instance.
|
|
|
|
///
|
|
|
|
/// ClangdServer uses \p CDB to obtain compilation arguments for parsing. Note
|
|
|
|
/// that ClangdServer only obtains compilation arguments once for each newly
|
|
|
|
/// added file (i.e., when processing a first call to addDocument) and reuses
|
|
|
|
/// those arguments for subsequent reparses. However, ClangdServer will check
|
|
|
|
/// if compilation arguments changed on calls to forceReparse().
|
2020-06-18 00:09:54 +08:00
|
|
|
ClangdServer(const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS,
|
|
|
|
const Options &Opts, Callbacks *Callbacks = nullptr);
|
2020-01-24 21:08:56 +08:00
|
|
|
|
2017-05-16 17:38:59 +08:00
|
|
|
/// Add a \p File to the list of tracked C++ files or update the contents if
|
|
|
|
/// \p File is already tracked. Also schedules parsing of the AST for it on a
|
|
|
|
/// separate thread. When the parsing is complete, DiagConsumer passed in
|
|
|
|
/// constructor will receive onDiagnosticsReady callback.
|
[clangd] Track document versions, include them with diags, enhance logs
Summary:
This ties to an LSP feature (diagnostic versioning) but really a lot
of the value is in being able to log what's happening with file versions
and queues more descriptively and clearly.
As such it's fairly invasive, for a logging patch :-\
Key decisions:
- at the LSP layer, we don't reqire the client to provide versions (LSP
makes it mandatory but we never enforced it). If not provided,
versions start at 0 and increment. DraftStore handles this.
- don't propagate magically using contexts, but rather manually:
addDocument -> ParseInputs -> (ParsedAST, Preamble, various callbacks)
Context-propagation would hide the versions from ClangdServer, which
would make producing good log messages hard
- within ClangdServer, treat versions as opaque and unordered.
std::string is a convenient type for this, and allows richer versions
for embedders. They're "mandatory" but "null" is a reasonable default.
Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75582
2020-03-04 07:33:29 +08:00
|
|
|
/// Version identifies this snapshot and is propagated to ASTs, preambles,
|
|
|
|
/// diagnostics etc built from it.
|
2018-02-22 21:11:12 +08:00
|
|
|
void addDocument(PathRef File, StringRef Contents,
|
[clangd] Track document versions, include them with diags, enhance logs
Summary:
This ties to an LSP feature (diagnostic versioning) but really a lot
of the value is in being able to log what's happening with file versions
and queues more descriptively and clearly.
As such it's fairly invasive, for a logging patch :-\
Key decisions:
- at the LSP layer, we don't reqire the client to provide versions (LSP
makes it mandatory but we never enforced it). If not provided,
versions start at 0 and increment. DraftStore handles this.
- don't propagate magically using contexts, but rather manually:
addDocument -> ParseInputs -> (ParsedAST, Preamble, various callbacks)
Context-propagation would hide the versions from ClangdServer, which
would make producing good log messages hard
- within ClangdServer, treat versions as opaque and unordered.
std::string is a convenient type for this, and allows richer versions
for embedders. They're "mandatory" but "null" is a reasonable default.
Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75582
2020-03-04 07:33:29 +08:00
|
|
|
llvm::StringRef Version = "null",
|
2020-02-04 04:14:49 +08:00
|
|
|
WantDiagnostics WD = WantDiagnostics::Auto,
|
|
|
|
bool ForceRebuild = false);
|
[clangd] Pass Context implicitly using TLS.
Summary:
Instead of passing Context explicitly around, we now have a thread-local
Context object `Context::current()` which is an implicit argument to
every function.
Most manipulation of this should use the WithContextValue helper, which
augments the current Context to add a single KV pair, and restores the
old context on destruction.
Advantages are:
- less boilerplate in functions that just propagate contexts
- reading most code doesn't require understanding context at all, and
using context as values in fewer places still
- fewer options to pass the "wrong" context when it changes within a
scope (e.g. when using Span)
- contexts pass through interfaces we can't modify, such as VFS
- propagating contexts across threads was slightly tricky (e.g.
copy vs move, no move-init in lambdas), and is now encapsulated in
the threadpool
Disadvantages are all the usual TLS stuff - hidden magic, and
potential for higher memory usage on threads that don't use the
context. (In practice, it's just one pointer)
Reviewers: ilya-biryukov
Subscribers: klimek, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D42517
llvm-svn: 323872
2018-01-31 21:40:48 +08:00
|
|
|
|
2017-05-16 17:38:59 +08:00
|
|
|
/// Remove \p File from list of tracked files, schedule a request to free
|
[clangd] Cleanup: make diagnostics callbacks from TUScheduler non-racy
Summary:
Previously, removeDoc followed by an addDoc to TUScheduler resulted in
racy diagnostic responses, i.e. the old dianostics could be delivered
to the client after the new ones by TUScheduler.
To workaround this, we tracked a version number in ClangdServer and
discarded stale diagnostics. After this commit, the TUScheduler will
stop delivering diagnostics for removed files and the workaround in
ClangdServer is not required anymore.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: javed.absar, ioeric, MaskRay, jkorous, arphaman, jfb, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D54829
llvm-svn: 347468
2018-11-22 23:39:54 +08:00
|
|
|
/// resources associated with it. Pending diagnostics for closed files may not
|
|
|
|
/// be delivered, even if requested with WantDiags::Auto or WantDiags::Yes.
|
[clangd] Track document versions, include them with diags, enhance logs
Summary:
This ties to an LSP feature (diagnostic versioning) but really a lot
of the value is in being able to log what's happening with file versions
and queues more descriptively and clearly.
As such it's fairly invasive, for a logging patch :-\
Key decisions:
- at the LSP layer, we don't reqire the client to provide versions (LSP
makes it mandatory but we never enforced it). If not provided,
versions start at 0 and increment. DraftStore handles this.
- don't propagate magically using contexts, but rather manually:
addDocument -> ParseInputs -> (ParsedAST, Preamble, various callbacks)
Context-propagation would hide the versions from ClangdServer, which
would make producing good log messages hard
- within ClangdServer, treat versions as opaque and unordered.
std::string is a convenient type for this, and allows richer versions
for embedders. They're "mandatory" but "null" is a reasonable default.
Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75582
2020-03-04 07:33:29 +08:00
|
|
|
/// An empty set of diagnostics will be delivered, with Version = "".
|
2018-02-08 15:37:35 +08:00
|
|
|
void removeDocument(PathRef File);
|
[clangd] Pass Context implicitly using TLS.
Summary:
Instead of passing Context explicitly around, we now have a thread-local
Context object `Context::current()` which is an implicit argument to
every function.
Most manipulation of this should use the WithContextValue helper, which
augments the current Context to add a single KV pair, and restores the
old context on destruction.
Advantages are:
- less boilerplate in functions that just propagate contexts
- reading most code doesn't require understanding context at all, and
using context as values in fewer places still
- fewer options to pass the "wrong" context when it changes within a
scope (e.g. when using Span)
- contexts pass through interfaces we can't modify, such as VFS
- propagating contexts across threads was slightly tricky (e.g.
copy vs move, no move-init in lambdas), and is now encapsulated in
the threadpool
Disadvantages are all the usual TLS stuff - hidden magic, and
potential for higher memory usage on threads that don't use the
context. (In practice, it's just one pointer)
Reviewers: ilya-biryukov
Subscribers: klimek, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D42517
llvm-svn: 323872
2018-01-31 21:40:48 +08:00
|
|
|
|
2017-10-06 01:04:13 +08:00
|
|
|
/// Run code completion for \p File at \p Pos.
|
[clangd] Pass Context implicitly using TLS.
Summary:
Instead of passing Context explicitly around, we now have a thread-local
Context object `Context::current()` which is an implicit argument to
every function.
Most manipulation of this should use the WithContextValue helper, which
augments the current Context to add a single KV pair, and restores the
old context on destruction.
Advantages are:
- less boilerplate in functions that just propagate contexts
- reading most code doesn't require understanding context at all, and
using context as values in fewer places still
- fewer options to pass the "wrong" context when it changes within a
scope (e.g. when using Span)
- contexts pass through interfaces we can't modify, such as VFS
- propagating contexts across threads was slightly tricky (e.g.
copy vs move, no move-init in lambdas), and is now encapsulated in
the threadpool
Disadvantages are all the usual TLS stuff - hidden magic, and
potential for higher memory usage on threads that don't use the
context. (In practice, it's just one pointer)
Reviewers: ilya-biryukov
Subscribers: klimek, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D42517
llvm-svn: 323872
2018-01-31 21:40:48 +08:00
|
|
|
/// Request is processed asynchronously.
|
2017-10-06 01:04:13 +08:00
|
|
|
///
|
|
|
|
/// This method should only be called for currently tracked files. However, it
|
|
|
|
/// is safe to call removeDocument for \p File after this method returns, even
|
|
|
|
/// while returned future is not yet ready.
|
2017-10-25 17:35:10 +08:00
|
|
|
/// A version of `codeComplete` that runs \p Callback on the processing thread
|
|
|
|
/// when codeComplete results become available.
|
2018-09-13 20:58:36 +08:00
|
|
|
void codeComplete(PathRef File, Position Pos,
|
|
|
|
const clangd::CodeCompleteOptions &Opts,
|
|
|
|
Callback<CodeCompleteResult> CB);
|
[clangd] Pass Context implicitly using TLS.
Summary:
Instead of passing Context explicitly around, we now have a thread-local
Context object `Context::current()` which is an implicit argument to
every function.
Most manipulation of this should use the WithContextValue helper, which
augments the current Context to add a single KV pair, and restores the
old context on destruction.
Advantages are:
- less boilerplate in functions that just propagate contexts
- reading most code doesn't require understanding context at all, and
using context as values in fewer places still
- fewer options to pass the "wrong" context when it changes within a
scope (e.g. when using Span)
- contexts pass through interfaces we can't modify, such as VFS
- propagating contexts across threads was slightly tricky (e.g.
copy vs move, no move-init in lambdas), and is now encapsulated in
the threadpool
Disadvantages are all the usual TLS stuff - hidden magic, and
potential for higher memory usage on threads that don't use the
context. (In practice, it's just one pointer)
Reviewers: ilya-biryukov
Subscribers: klimek, jkorous-apple, ioeric, cfe-commits
Differential Revision: https://reviews.llvm.org/D42517
llvm-svn: 323872
2018-01-31 21:40:48 +08:00
|
|
|
|
2018-03-16 22:30:42 +08:00
|
|
|
/// Provide signature help for \p File at \p Pos. This method should only be
|
|
|
|
/// called for tracked files.
|
2018-03-13 07:22:35 +08:00
|
|
|
void signatureHelp(PathRef File, Position Pos, Callback<SignatureHelp> CB);
|
2017-10-06 19:54:17 +08:00
|
|
|
|
[clangd] Implement textDocument/declaration from LSP 3.14
Summary:
LSP now reflects the declaration/definition distinction.
Language server changes:
- textDocument/definition now returns a definition if one is found, otherwise
the declaration. It no longer returns declaration + definition if they are
distinct.
- textDocument/declaration returns the best declaration we can find.
- For macros, the active macro definition is returned for both methods.
- For include directive, the top of the target file is returned for both.
There doesn't appear to be a discovery mechanism (we can't return everything to
clients that only know about definition), so this changes existing behavior.
In practice, it should greatly reduce the fraction of the time we need to show
the user a menu of options.
C++ API changes:
- findDefinitions is replaced by locateSymbolAt, which returns a
vector<LocatedSymbol> - one for each symbol under the cursor.
- this contains the preferred declaration, the definition (if found), and
the symbol name
This API enables some potentially-neat extensions, like swapping between decl
and def, and exposing the symbol name to the UI in the case of multiple symbols.
Reviewers: hokein
Subscribers: ilya-biryukov, javed.absar, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D57388
llvm-svn: 352864
2019-02-01 19:26:13 +08:00
|
|
|
/// Find declaration/definition locations of symbol at a specified position.
|
|
|
|
void locateSymbolAt(PathRef File, Position Pos,
|
|
|
|
Callback<std::vector<LocatedSymbol>> CB);
|
2017-05-16 17:38:59 +08:00
|
|
|
|
2019-10-01 18:21:15 +08:00
|
|
|
/// Switch to a corresponding source file when given a header file, and vice
|
|
|
|
/// versa.
|
|
|
|
void switchSourceHeader(PathRef Path,
|
|
|
|
Callback<llvm::Optional<clangd::Path>> CB);
|
2017-09-28 11:14:40 +08:00
|
|
|
|
[clangd] Document highlights for clangd
Summary: Implementation of Document Highlights Request as described in
LSP.
Contributed by William Enright (nebiroth).
Reviewers: malaperle, krasimir, bkramer, ilya-biryukov
Reviewed By: malaperle
Subscribers: mgrang, sammccall, klimek, ioeric, rwols, cfe-commits, arphaman, ilya-biryukov
Differential Revision: https://reviews.llvm.org/D38425
llvm-svn: 320474
2017-12-12 20:27:47 +08:00
|
|
|
/// Get document highlights for a given position.
|
2018-03-13 07:22:35 +08:00
|
|
|
void findDocumentHighlights(PathRef File, Position Pos,
|
|
|
|
Callback<std::vector<DocumentHighlight>> CB);
|
[clangd] Document highlights for clangd
Summary: Implementation of Document Highlights Request as described in
LSP.
Contributed by William Enright (nebiroth).
Reviewers: malaperle, krasimir, bkramer, ilya-biryukov
Reviewed By: malaperle
Subscribers: mgrang, sammccall, klimek, ioeric, rwols, cfe-commits, arphaman, ilya-biryukov
Differential Revision: https://reviews.llvm.org/D38425
llvm-svn: 320474
2017-12-12 20:27:47 +08:00
|
|
|
|
[clangd] Implement textDocument/hover
Summary: Implemention of textDocument/hover as described in LSP definition.
This patch adds a basic Hover implementation. When hovering a variable,
function, method or namespace, clangd will return a text containing the
declaration's scope, as well as the declaration of the hovered entity.
For example, for a variable:
Declared in class Foo::Bar
int hello = 2
For macros, the macro definition is returned.
This patch doesn't include:
- markdown support (the client I use doesn't support it yet)
- range support (optional in the Hover response)
- comments associated to variables/functions/classes
They are kept as future work to keep this patch simpler.
I added tests in XRefsTests.cpp. hover.test contains one simple
smoketest to make sure the feature works from a black box perspective.
Reviewers: malaperle, krasimir, bkramer, ilya-biryukov
Subscribers: sammccall, mgrang, klimek, rwols, ilya-biryukov, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D35894
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
Signed-off-by: William Enright <william.enright@polymtl.ca>
llvm-svn: 325395
2018-02-17 05:38:15 +08:00
|
|
|
/// Get code hover for a given position.
|
2018-06-04 18:37:16 +08:00
|
|
|
void findHover(PathRef File, Position Pos,
|
2019-05-28 18:29:58 +08:00
|
|
|
Callback<llvm::Optional<HoverInfo>> CB);
|
[clangd] Implement textDocument/hover
Summary: Implemention of textDocument/hover as described in LSP definition.
This patch adds a basic Hover implementation. When hovering a variable,
function, method or namespace, clangd will return a text containing the
declaration's scope, as well as the declaration of the hovered entity.
For example, for a variable:
Declared in class Foo::Bar
int hello = 2
For macros, the macro definition is returned.
This patch doesn't include:
- markdown support (the client I use doesn't support it yet)
- range support (optional in the Hover response)
- comments associated to variables/functions/classes
They are kept as future work to keep this patch simpler.
I added tests in XRefsTests.cpp. hover.test contains one simple
smoketest to make sure the feature works from a black box perspective.
Reviewers: malaperle, krasimir, bkramer, ilya-biryukov
Subscribers: sammccall, mgrang, klimek, rwols, ilya-biryukov, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D35894
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
Signed-off-by: William Enright <william.enright@polymtl.ca>
llvm-svn: 325395
2018-02-17 05:38:15 +08:00
|
|
|
|
[clangd] Add support for type hierarchy (super types only for now)
Summary:
Patch by Nathan Ridge(@nridge)!
This is an LSP extension proposed here:
https://github.com/Microsoft/vscode-languageserver-node/pull/426
An example client implementation can be found here:
https://github.com/theia-ide/theia/pull/3802
Reviewers: kadircet, sammccall
Reviewed By: kadircet
Subscribers: jdoerfert, sammccall, cfe-commits, mgorny, dschaefer, simark, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet
Tags: #clang
Differential Revision: https://reviews.llvm.org/D56370
llvm-svn: 356445
2019-03-19 17:27:04 +08:00
|
|
|
/// Get information about type hierarchy for a given position.
|
|
|
|
void typeHierarchy(PathRef File, Position Pos, int Resolve,
|
|
|
|
TypeHierarchyDirection Direction,
|
|
|
|
Callback<llvm::Optional<TypeHierarchyItem>> CB);
|
|
|
|
|
2019-07-13 11:24:48 +08:00
|
|
|
/// Resolve type hierarchy item in the given direction.
|
|
|
|
void resolveTypeHierarchy(TypeHierarchyItem Item, int Resolve,
|
|
|
|
TypeHierarchyDirection Direction,
|
|
|
|
Callback<llvm::Optional<TypeHierarchyItem>> CB);
|
|
|
|
|
[clangd] Implementation of workspace/symbol request
Summary:
This is a basic implementation of the "workspace/symbol" request which is
used to find symbols by a string query. Since this is similar to code completion
in terms of result, this implementation reuses the "fuzzyFind" in order to get
matches. For now, the scoring algorithm is the same as code completion and
improvements could be done in the future.
The index model doesn't contain quite enough symbols for this to cover
common symbols like methods, enum class enumerators, functions in unamed
namespaces, etc. The index model will be augmented separately to achieve this.
Reviewers: sammccall, ilya-biryukov
Reviewed By: sammccall
Subscribers: jkorous, hokein, simark, sammccall, klimek, mgorny, ilya-biryukov, mgrang, jkorous-apple, ioeric, MaskRay, cfe-commits
Differential Revision: https://reviews.llvm.org/D44882
llvm-svn: 330637
2018-04-24 04:00:52 +08:00
|
|
|
/// Retrieve the top symbols from the workspace matching a query.
|
|
|
|
void workspaceSymbols(StringRef Query, int Limit,
|
|
|
|
Callback<std::vector<SymbolInformation>> CB);
|
|
|
|
|
2018-07-06 03:35:01 +08:00
|
|
|
/// Retrieve the symbols within the specified file.
|
|
|
|
void documentSymbols(StringRef File,
|
2018-11-23 23:21:19 +08:00
|
|
|
Callback<std::vector<DocumentSymbol>> CB);
|
2018-07-06 03:35:01 +08:00
|
|
|
|
[clangd] Implement textDocument/foldingRange
Summary:
This patch introduces basic textDocument/foldingRange support. It relies on
textDocument/documentSymbols to collect all symbols and uses takes ranges
to create folds.
The next steps for textDocument/foldingRange support would be:
* Implementing FoldingRangeClientCapabilities and respecting respect client
preferences
* Specifying folding range kind
* Migrating from DocumentSymbol implementation to custom RecursiveASTVisitor flow that will allow more flexibility
* Supporting more folding range types: comments, PP conditional regions, includes and other code regions (e.g. public/private/protected sections of classes, control flow statement bodies)
Tested: (Neo)Vim (coc-clangd) and VSCode.
Related issue: https://github.com/clangd/clangd/issues/310
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: nridge, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82436
2020-07-14 15:28:38 +08:00
|
|
|
/// Retrieve ranges that can be used to fold code within the specified file.
|
|
|
|
void foldingRanges(StringRef File, Callback<std::vector<FoldingRange>> CB);
|
|
|
|
|
2018-09-05 19:53:07 +08:00
|
|
|
/// Retrieve locations for symbol references.
|
2019-01-15 02:11:09 +08:00
|
|
|
void findReferences(PathRef File, Position Pos, uint32_t Limit,
|
2019-11-18 18:35:00 +08:00
|
|
|
Callback<ReferencesResult> CB);
|
2018-09-05 19:53:07 +08:00
|
|
|
|
2017-12-13 04:25:06 +08:00
|
|
|
/// Run formatting for \p Rng inside \p File with content \p Code.
|
[clangd] Run formatting operations asynchronously.
Summary:
They don't need ASTs or anything, so they should still run immediately.
These were sync for historical reasons (they predate clangd having a pervasive
threading model). This worked ok as they were "cheap".
Aside for consistency, there are a couple of reasons to make them async:
- they do IO (finding .clang-format) so aren't trivially cheap
- having TUScheduler involved in running these tasks means we can use it as
an injection point for configuration.
(TUScheduler::run will need to learn about which file is being operated on,
but that's an easy change).
- adding the config system adds more potential IO, too
Reviewers: kbobyrev
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82642
2020-06-26 18:57:29 +08:00
|
|
|
void formatRange(PathRef File, StringRef Code, Range Rng,
|
|
|
|
Callback<tooling::Replacements> CB);
|
2017-12-13 04:25:06 +08:00
|
|
|
|
|
|
|
/// Run formatting for the whole \p File with content \p Code.
|
[clangd] Run formatting operations asynchronously.
Summary:
They don't need ASTs or anything, so they should still run immediately.
These were sync for historical reasons (they predate clangd having a pervasive
threading model). This worked ok as they were "cheap".
Aside for consistency, there are a couple of reasons to make them async:
- they do IO (finding .clang-format) so aren't trivially cheap
- having TUScheduler involved in running these tasks means we can use it as
an injection point for configuration.
(TUScheduler::run will need to learn about which file is being operated on,
but that's an easy change).
- adding the config system adds more potential IO, too
Reviewers: kbobyrev
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82642
2020-06-26 18:57:29 +08:00
|
|
|
void formatFile(PathRef File, StringRef Code,
|
|
|
|
Callback<tooling::Replacements> CB);
|
2017-12-13 04:25:06 +08:00
|
|
|
|
[clangd] Revamp textDocument/onTypeFormatting.
Summary:
The existing implementation (which triggers on }) is fairly simple and
has flaws:
- doesn't trigger frequently/regularly enough (particularly in editors that type the }
for you)
- often reformats too much code around the edit
- has jarring cases that I don't have clear ideas for fixing
This implementation is designed to trigger on newline, which feels to me more
intuitive than } or ;.
It does have allow for reformatting after other characters - it has a
basic behavior and a model for adding specialized behavior for
particular characters. But at least initially I'd stick to advertising
\n in the capabilities.
This also handles comment splitting: when you insert a line break inside
a line comment, it will make the new line into an aligned line comment.
Working on tests, but want people to patch it in and try it - it's hard to
see if "feel" is right purely by looking at a test.
Reviewers: ilya-biryukov, hokein
Subscribers: mgorny, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D60605
llvm-svn: 362939
2019-06-10 22:26:21 +08:00
|
|
|
/// Run formatting after \p TriggerText was typed at \p Pos in \p File with
|
2017-12-13 04:25:06 +08:00
|
|
|
/// content \p Code.
|
[clangd] Run formatting operations asynchronously.
Summary:
They don't need ASTs or anything, so they should still run immediately.
These were sync for historical reasons (they predate clangd having a pervasive
threading model). This worked ok as they were "cheap".
Aside for consistency, there are a couple of reasons to make them async:
- they do IO (finding .clang-format) so aren't trivially cheap
- having TUScheduler involved in running these tasks means we can use it as
an injection point for configuration.
(TUScheduler::run will need to learn about which file is being operated on,
but that's an easy change).
- adding the config system adds more potential IO, too
Reviewers: kbobyrev
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82642
2020-06-26 18:57:29 +08:00
|
|
|
void formatOnType(PathRef File, StringRef Code, Position Pos,
|
|
|
|
StringRef TriggerText, Callback<std::vector<TextEdit>> CB);
|
2017-12-13 04:25:06 +08:00
|
|
|
|
2019-07-24 15:49:23 +08:00
|
|
|
/// Test the validity of a rename operation.
|
|
|
|
void prepareRename(PathRef File, Position Pos,
|
2020-02-19 22:37:36 +08:00
|
|
|
const RenameOptions &RenameOpts,
|
2019-07-24 15:49:23 +08:00
|
|
|
Callback<llvm::Optional<Range>> CB);
|
|
|
|
|
2017-11-09 19:30:04 +08:00
|
|
|
/// Rename all occurrences of the symbol at the \p Pos in \p File to
|
|
|
|
/// \p NewName.
|
2019-07-10 21:44:22 +08:00
|
|
|
/// If WantFormat is false, the final TextEdit will be not formatted,
|
|
|
|
/// embedders could use this method to get all occurrences of the symbol (e.g.
|
|
|
|
/// highlighting them in prepare stage).
|
2020-02-19 22:37:36 +08:00
|
|
|
void rename(PathRef File, Position Pos, llvm::StringRef NewName,
|
|
|
|
const RenameOptions &Opts, Callback<FileEdits> CB);
|
2017-05-16 22:40:30 +08:00
|
|
|
|
[clangd] Interfaces for writing code tweaks
Summary:
The code tweaks are an implementation of mini-refactorings exposed
via the LSP code actions. They run in two stages:
- Stage 1. Decides whether the action is available to the user and
collects all the information required to finish the action.
Should be cheap, since this will run over all the actions known to
clangd on each textDocument/codeAction request from the client.
- Stage 2. Uses information from stage 1 to produce the actual edits
that the code action should perform. This stage can be expensive and
will only run if the user chooses to perform the specified action in
the UI.
One unfortunate consequence of this change is increased latency of
processing the textDocument/codeAction requests, which now wait for an
AST. However, we cannot avoid this with what we have available in the LSP
today.
Reviewers: kadircet, ioeric, hokein, sammccall
Reviewed By: sammccall
Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D56267
llvm-svn: 352494
2019-01-29 22:17:36 +08:00
|
|
|
struct TweakRef {
|
2019-02-01 13:41:50 +08:00
|
|
|
std::string ID; /// ID to pass for applyTweak.
|
[clangd] Interfaces for writing code tweaks
Summary:
The code tweaks are an implementation of mini-refactorings exposed
via the LSP code actions. They run in two stages:
- Stage 1. Decides whether the action is available to the user and
collects all the information required to finish the action.
Should be cheap, since this will run over all the actions known to
clangd on each textDocument/codeAction request from the client.
- Stage 2. Uses information from stage 1 to produce the actual edits
that the code action should perform. This stage can be expensive and
will only run if the user chooses to perform the specified action in
the UI.
One unfortunate consequence of this change is increased latency of
processing the textDocument/codeAction requests, which now wait for an
AST. However, we cannot avoid this with what we have available in the LSP
today.
Reviewers: kadircet, ioeric, hokein, sammccall
Reviewed By: sammccall
Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D56267
llvm-svn: 352494
2019-01-29 22:17:36 +08:00
|
|
|
std::string Title; /// A single-line message to show in the UI.
|
2019-06-18 21:37:54 +08:00
|
|
|
Tweak::Intent Intent;
|
[clangd] Interfaces for writing code tweaks
Summary:
The code tweaks are an implementation of mini-refactorings exposed
via the LSP code actions. They run in two stages:
- Stage 1. Decides whether the action is available to the user and
collects all the information required to finish the action.
Should be cheap, since this will run over all the actions known to
clangd on each textDocument/codeAction request from the client.
- Stage 2. Uses information from stage 1 to produce the actual edits
that the code action should perform. This stage can be expensive and
will only run if the user chooses to perform the specified action in
the UI.
One unfortunate consequence of this change is increased latency of
processing the textDocument/codeAction requests, which now wait for an
AST. However, we cannot avoid this with what we have available in the LSP
today.
Reviewers: kadircet, ioeric, hokein, sammccall
Reviewed By: sammccall
Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D56267
llvm-svn: 352494
2019-01-29 22:17:36 +08:00
|
|
|
};
|
|
|
|
/// Enumerate the code tweaks available to the user at a specified point.
|
|
|
|
void enumerateTweaks(PathRef File, Range Sel,
|
|
|
|
Callback<std::vector<TweakRef>> CB);
|
|
|
|
|
|
|
|
/// Apply the code tweak with a specified \p ID.
|
2019-02-01 13:41:50 +08:00
|
|
|
void applyTweak(PathRef File, Range Sel, StringRef ID,
|
2019-06-19 15:29:10 +08:00
|
|
|
Callback<Tweak::Effect> CB);
|
[clangd] Interfaces for writing code tweaks
Summary:
The code tweaks are an implementation of mini-refactorings exposed
via the LSP code actions. They run in two stages:
- Stage 1. Decides whether the action is available to the user and
collects all the information required to finish the action.
Should be cheap, since this will run over all the actions known to
clangd on each textDocument/codeAction request from the client.
- Stage 2. Uses information from stage 1 to produce the actual edits
that the code action should perform. This stage can be expensive and
will only run if the user chooses to perform the specified action in
the UI.
One unfortunate consequence of this change is increased latency of
processing the textDocument/codeAction requests, which now wait for an
AST. However, we cannot avoid this with what we have available in the LSP
today.
Reviewers: kadircet, ioeric, hokein, sammccall
Reviewed By: sammccall
Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D56267
llvm-svn: 352494
2019-01-29 22:17:36 +08:00
|
|
|
|
2017-10-03 02:00:37 +08:00
|
|
|
/// Called when an event occurs for a watched file in the workspace.
|
|
|
|
void onFileEvent(const DidChangeWatchedFilesParams &Params);
|
2017-05-16 17:38:59 +08:00
|
|
|
|
2018-11-28 00:40:46 +08:00
|
|
|
/// Get symbol info for given position.
|
|
|
|
/// Clangd extension - not part of official LSP.
|
|
|
|
void symbolInfo(PathRef File, Position Pos,
|
|
|
|
Callback<std::vector<SymbolDetails>> CB);
|
|
|
|
|
2019-09-17 18:28:05 +08:00
|
|
|
/// Get semantic ranges around a specified position in a file.
|
2020-03-25 07:51:50 +08:00
|
|
|
void semanticRanges(PathRef File, const std::vector<Position> &Pos,
|
|
|
|
Callback<std::vector<SelectionRange>> CB);
|
2019-09-17 18:28:05 +08:00
|
|
|
|
2019-12-17 02:08:51 +08:00
|
|
|
/// Get all document links in a file.
|
|
|
|
void documentLinks(PathRef File, Callback<std::vector<DocumentLink>> CB);
|
2020-03-24 09:24:47 +08:00
|
|
|
|
|
|
|
void semanticHighlights(PathRef File,
|
|
|
|
Callback<std::vector<HighlightingToken>>);
|
|
|
|
|
2020-08-13 16:43:51 +08:00
|
|
|
/// Runs an arbitrary action that has access to the AST of the specified file.
|
|
|
|
/// The action will execute on one of ClangdServer's internal threads.
|
|
|
|
/// The AST is only valid for the duration of the callback.
|
|
|
|
/// As with other actions, the file must have been opened.
|
|
|
|
void customAction(PathRef File, llvm::StringRef Name,
|
|
|
|
Callback<InputsAndAST> Action);
|
|
|
|
|
2020-04-14 04:07:12 +08:00
|
|
|
/// Returns estimated memory usage and other statistics for each of the
|
|
|
|
/// currently open files.
|
2018-01-25 22:32:21 +08:00
|
|
|
/// Overall memory usage of clangd may be significantly more than reported
|
|
|
|
/// here, as this metric does not account (at least) for:
|
|
|
|
/// - memory occupied by static and dynamic index,
|
|
|
|
/// - memory required for in-flight requests,
|
|
|
|
/// FIXME: those metrics might be useful too, we should add them.
|
2020-04-14 04:07:12 +08:00
|
|
|
llvm::StringMap<TUScheduler::FileStats> fileStats() const;
|
2018-01-25 22:32:21 +08:00
|
|
|
|
2018-02-13 16:59:23 +08:00
|
|
|
// Blocks the main thread until the server is idle. Only for use in tests.
|
|
|
|
// Returns false if the timeout expires.
|
|
|
|
LLVM_NODISCARD bool
|
|
|
|
blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
|
|
|
|
|
2017-05-23 21:42:59 +08:00
|
|
|
private:
|
[clangd] Run formatting operations asynchronously.
Summary:
They don't need ASTs or anything, so they should still run immediately.
These were sync for historical reasons (they predate clangd having a pervasive
threading model). This worked ok as they were "cheap".
Aside for consistency, there are a couple of reasons to make them async:
- they do IO (finding .clang-format) so aren't trivially cheap
- having TUScheduler involved in running these tasks means we can use it as
an injection point for configuration.
(TUScheduler::run will need to learn about which file is being operated on,
but that's an easy change).
- adding the config system adds more potential IO, too
Reviewers: kbobyrev
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82642
2020-06-26 18:57:29 +08:00
|
|
|
void formatCode(PathRef File, llvm::StringRef Code,
|
|
|
|
ArrayRef<tooling::Range> Ranges,
|
|
|
|
Callback<tooling::Replacements> CB);
|
2017-12-13 04:25:06 +08:00
|
|
|
|
2020-07-03 05:09:25 +08:00
|
|
|
/// Derives a context for a task processing the specified source file.
|
|
|
|
/// This includes the current configuration (see Options::ConfigProvider).
|
|
|
|
/// The empty string means no particular file is the target.
|
|
|
|
/// Rather than called by each feature, this is exposed to the components
|
|
|
|
/// that control worker threads, like TUScheduler and BackgroundIndex.
|
|
|
|
/// This means it's OK to do some IO here, and it cuts across all features.
|
|
|
|
Context createProcessingContext(PathRef) const;
|
|
|
|
config::Provider *ConfigProvider = nullptr;
|
|
|
|
|
2020-06-18 00:09:54 +08:00
|
|
|
const ThreadsafeFS &TFS;
|
2018-03-16 22:30:42 +08:00
|
|
|
|
2018-06-13 17:20:41 +08:00
|
|
|
Path ResourceDir;
|
2018-01-15 20:33:00 +08:00
|
|
|
// The index used to look up symbols. This could be:
|
|
|
|
// - null (all index functionality is optional)
|
2018-08-22 20:43:17 +08:00
|
|
|
// - the dynamic index owned by ClangdServer (DynamicIdx)
|
2018-01-15 20:33:00 +08:00
|
|
|
// - the static index passed to the constructor
|
|
|
|
// - a merged view of a static and dynamic index (MergedIndex)
|
[clangd] Enable auto-index behind a flag.
Summary:
Ownership and configuration:
The auto-index (background index) is maintained by ClangdServer, like Dynamic.
(This means ClangdServer will be able to enqueue preamble indexing in future).
For now it's enabled by a simple boolean flag in ClangdServer::Options, but
we probably want to eventually allow injecting the storage strategy.
New 'sync' command:
In order to meaningfully test the integration (not just unit-test components)
we need a way for tests to ensure the asynchronous index reads/writes occur
before a certain point.
Because these tests and assertions are few, I think exposing an explicit "sync"
command for use in tests is simpler than allowing threading to be completely
disabled in the background index (as we do for TUScheduler).
Bugs:
I fixed a couple of trivial bugs I found while testing, but there's one I can't.
JSONCompilationDatabase::getAllFiles() may return relative paths, and currently
we trigger an assertion that assumes they are absolute.
There's no efficient way to resolve them (you have to retrieve the corresponding
command and then resolve against its directory property). In general I think
this behavior is broken and we should fix it in JSONCompilationDatabase and
require CompilationDatabase::getAllFiles() to be absolute.
Reviewers: kadircet
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D54894
llvm-svn: 347567
2018-11-27 00:00:11 +08:00
|
|
|
const SymbolIndex *Index = nullptr;
|
2018-09-04 00:37:59 +08:00
|
|
|
// If present, an index of symbols in open files. Read via *Index.
|
2018-09-18 18:30:44 +08:00
|
|
|
std::unique_ptr<FileIndex> DynamicIdx;
|
[clangd] Enable auto-index behind a flag.
Summary:
Ownership and configuration:
The auto-index (background index) is maintained by ClangdServer, like Dynamic.
(This means ClangdServer will be able to enqueue preamble indexing in future).
For now it's enabled by a simple boolean flag in ClangdServer::Options, but
we probably want to eventually allow injecting the storage strategy.
New 'sync' command:
In order to meaningfully test the integration (not just unit-test components)
we need a way for tests to ensure the asynchronous index reads/writes occur
before a certain point.
Because these tests and assertions are few, I think exposing an explicit "sync"
command for use in tests is simpler than allowing threading to be completely
disabled in the background index (as we do for TUScheduler).
Bugs:
I fixed a couple of trivial bugs I found while testing, but there's one I can't.
JSONCompilationDatabase::getAllFiles() may return relative paths, and currently
we trigger an assertion that assumes they are absolute.
There's no efficient way to resolve them (you have to retrieve the corresponding
command and then resolve against its directory property). In general I think
this behavior is broken and we should fix it in JSONCompilationDatabase and
require CompilationDatabase::getAllFiles() to be absolute.
Reviewers: kadircet
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D54894
llvm-svn: 347567
2018-11-27 00:00:11 +08:00
|
|
|
// If present, the new "auto-index" maintained in background threads.
|
|
|
|
std::unique_ptr<BackgroundIndex> BackgroundIdx;
|
|
|
|
// Storage for merged views of the various indexes.
|
|
|
|
std::vector<std::unique_ptr<SymbolIndex>> MergedIdx;
|
[clangd] Speculative code completion index request before Sema is run.
Summary:
For index-based code completion, send an asynchronous speculative index
request, based on the index request for the last code completion on the same
file and the filter text typed before the cursor, before sema code completion
is invoked. This can reduce the code completion latency (by roughly latency of
sema code completion) if the speculative request is the same as the one
generated for the ongoing code completion from sema. As a sequence of code
completions often have the same scopes and proximity paths etc, this should be
effective for a number of code completions.
Trace with speculative index request:{F6997544}
Reviewers: hokein, ilya-biryukov
Reviewed By: ilya-biryukov
Subscribers: javed.absar, jfb, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D50962
llvm-svn: 340604
2018-08-24 19:23:56 +08:00
|
|
|
|
2019-05-21 01:30:46 +08:00
|
|
|
// When set, provides clang-tidy options for a specific file.
|
|
|
|
ClangTidyOptionsBuilder GetClangTidyOptions;
|
2019-01-22 17:39:05 +08:00
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
// If this is true, suggest include insertion fixes for diagnostic errors that
|
|
|
|
// can be caused by missing includes (e.g. member access in incomplete type).
|
|
|
|
bool SuggestMissingIncludes = false;
|
2019-07-12 11:26:32 +08:00
|
|
|
|
2020-03-31 22:09:49 +08:00
|
|
|
// If true, preserve expressions in AST for broken code.
|
2020-06-12 22:05:38 +08:00
|
|
|
bool BuildRecoveryAST = true;
|
2020-05-19 21:21:50 +08:00
|
|
|
// If true, preserve the type for recovery AST.
|
|
|
|
bool PreserveRecoveryASTType = false;
|
2020-03-31 22:09:49 +08:00
|
|
|
|
2019-07-12 16:50:20 +08:00
|
|
|
std::function<bool(const Tweak &)> TweakFilter;
|
2019-07-02 00:55:29 +08:00
|
|
|
|
[clangd] Speculative code completion index request before Sema is run.
Summary:
For index-based code completion, send an asynchronous speculative index
request, based on the index request for the last code completion on the same
file and the filter text typed before the cursor, before sema code completion
is invoked. This can reduce the code completion latency (by roughly latency of
sema code completion) if the speculative request is the same as the one
generated for the ongoing code completion from sema. As a sequence of code
completions often have the same scopes and proximity paths etc, this should be
effective for a number of code completions.
Trace with speculative index request:{F6997544}
Reviewers: hokein, ilya-biryukov
Reviewed By: ilya-biryukov
Subscribers: javed.absar, jfb, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D50962
llvm-svn: 340604
2018-08-24 19:23:56 +08:00
|
|
|
// GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
|
|
|
|
llvm::StringMap<llvm::Optional<FuzzyFindRequest>>
|
|
|
|
CachedCompletionFuzzyFindRequestByFile;
|
|
|
|
mutable std::mutex CachedCompletionFuzzyFindRequestMutex;
|
|
|
|
|
2018-10-19 23:42:23 +08:00
|
|
|
llvm::Optional<std::string> WorkspaceRoot;
|
2017-09-21 03:32:06 +08:00
|
|
|
// WorkScheduler has to be the last member, because its destructor has to be
|
|
|
|
// called before all other members to stop the worker thread that references
|
2018-01-31 16:51:16 +08:00
|
|
|
// ClangdServer.
|
|
|
|
TUScheduler WorkScheduler;
|
2017-05-16 17:38:59 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|
|
|
|
|
|
|
|
#endif
|