Skip to content

Commit a7534dc

Browse files
committed
[clangd] Populate the parse options to CodeCompletion/SignatureHelp.
Summary: A followup of D79938. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D81066
1 parent 2ba4df1 commit a7534dc

File tree

5 files changed

+71
-71
lines changed

5 files changed

+71
-71
lines changed

Diff for: clang-tools-extra/clangd/ClangdServer.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,16 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
238238
}
239239
}
240240
}
241+
ParseInputs ParseInput{IP->Command, FS, IP->Contents.str()};
242+
ParseInput.Index = Index;
243+
ParseInput.Opts.BuildRecoveryAST = BuildRecoveryAST;
244+
ParseInput.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
245+
241246
// FIXME(ibiryukov): even if Preamble is non-null, we may want to check
242247
// both the old and the new version in case only one of them matches.
243248
CodeCompleteResult Result = clangd::codeComplete(
244-
File, IP->Command, IP->Preamble, IP->Contents, Pos, FS,
245-
CodeCompleteOpts, SpecFuzzyFind ? SpecFuzzyFind.getPointer() : nullptr);
249+
File, Pos, IP->Preamble, ParseInput, CodeCompleteOpts,
250+
SpecFuzzyFind ? SpecFuzzyFind.getPointer() : nullptr);
246251
{
247252
clang::clangd::trace::Span Tracer("Completion results callback");
248253
CB(std::move(Result));
@@ -281,8 +286,11 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos,
281286
return CB(llvm::createStringError(llvm::inconvertibleErrorCode(),
282287
"Failed to parse includes"));
283288

284-
CB(clangd::signatureHelp(File, IP->Command, *PreambleData, IP->Contents,
285-
Pos, FS, Index));
289+
ParseInputs ParseInput{IP->Command, FS, IP->Contents.str()};
290+
ParseInput.Index = Index;
291+
ParseInput.Opts.BuildRecoveryAST = BuildRecoveryAST;
292+
ParseInput.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
293+
CB(clangd::signatureHelp(File, Pos, *PreambleData, ParseInput));
286294
};
287295

288296
// Unlike code completion, we wait for a preamble here.

Diff for: clang-tools-extra/clangd/CodeComplete.cpp

+33-45
Original file line numberDiff line numberDiff line change
@@ -1029,12 +1029,10 @@ class SignatureHelpCollector final : public CodeCompleteConsumer {
10291029

10301030
struct SemaCompleteInput {
10311031
PathRef FileName;
1032-
const tooling::CompileCommand &Command;
1032+
size_t Offset;
10331033
const PreambleData &Preamble;
10341034
const llvm::Optional<PreamblePatch> Patch;
1035-
llvm::StringRef Contents;
1036-
size_t Offset;
1037-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
1035+
const ParseInputs &ParseInput;
10381036
};
10391037

10401038
void loadMainFilePreambleMacros(const Preprocessor &PP,
@@ -1062,17 +1060,12 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
10621060
const SemaCompleteInput &Input,
10631061
IncludeStructure *Includes = nullptr) {
10641062
trace::Span Tracer("Sema completion");
1065-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = Input.VFS;
1063+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = Input.ParseInput.FS;
10661064
if (Input.Preamble.StatCache)
10671065
VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
1068-
ParseInputs ParseInput;
1069-
ParseInput.CompileCommand = Input.Command;
1070-
ParseInput.FS = VFS;
1071-
ParseInput.Contents = std::string(Input.Contents);
1072-
// FIXME: setup the recoveryAST and recoveryASTType in ParseInput properly.
10731066

10741067
IgnoreDiagnostics IgnoreDiags;
1075-
auto CI = buildCompilerInvocation(ParseInput, IgnoreDiags);
1068+
auto CI = buildCompilerInvocation(Input.ParseInput, IgnoreDiags);
10761069
if (!CI) {
10771070
elog("Couldn't create CompilerInvocation");
10781071
return false;
@@ -1090,10 +1083,11 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
10901083
FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName);
10911084
std::tie(FrontendOpts.CodeCompletionAt.Line,
10921085
FrontendOpts.CodeCompletionAt.Column) =
1093-
offsetToClangLineColumn(Input.Contents, Input.Offset);
1086+
offsetToClangLineColumn(Input.ParseInput.Contents, Input.Offset);
10941087

10951088
std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
1096-
llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName);
1089+
llvm::MemoryBuffer::getMemBufferCopy(Input.ParseInput.Contents,
1090+
Input.FileName);
10971091
// The diagnostic options must be set before creating a CompilerInstance.
10981092
CI->getDiagnosticOpts().IgnoreWarnings = true;
10991093
// We reuse the preamble whether it's valid or not. This is a
@@ -1260,9 +1254,9 @@ class CodeCompleteFlow {
12601254

12611255
CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && {
12621256
trace::Span Tracer("CodeCompleteFlow");
1263-
HeuristicPrefix =
1264-
guessCompletionPrefix(SemaCCInput.Contents, SemaCCInput.Offset);
1265-
populateContextWords(SemaCCInput.Contents);
1257+
HeuristicPrefix = guessCompletionPrefix(SemaCCInput.ParseInput.Contents,
1258+
SemaCCInput.Offset);
1259+
populateContextWords(SemaCCInput.ParseInput.Contents);
12661260
if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq.hasValue()) {
12671261
assert(!SpecFuzzyFind->Result.valid());
12681262
SpecReq = speculativeFuzzyFindRequestForCompletion(
@@ -1278,13 +1272,14 @@ class CodeCompleteFlow {
12781272
assert(Recorder && "Recorder is not set");
12791273
CCContextKind = Recorder->CCContext.getKind();
12801274
IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
1281-
auto Style = getFormatStyleForFile(
1282-
SemaCCInput.FileName, SemaCCInput.Contents, SemaCCInput.VFS.get());
1275+
auto Style = getFormatStyleForFile(SemaCCInput.FileName,
1276+
SemaCCInput.ParseInput.Contents,
1277+
SemaCCInput.ParseInput.FS.get());
12831278
// If preprocessor was run, inclusions from preprocessor callback should
12841279
// already be added to Includes.
12851280
Inserter.emplace(
1286-
SemaCCInput.FileName, SemaCCInput.Contents, Style,
1287-
SemaCCInput.Command.Directory,
1281+
SemaCCInput.FileName, SemaCCInput.ParseInput.Contents, Style,
1282+
SemaCCInput.ParseInput.CompileCommand.Directory,
12881283
&Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
12891284
for (const auto &Inc : Includes.MainFileIncludes)
12901285
Inserter->addExisting(Inc);
@@ -1750,12 +1745,12 @@ CompletionPrefix guessCompletionPrefix(llvm::StringRef Content,
17501745
return Result;
17511746
}
17521747

1753-
CodeCompleteResult
1754-
codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
1755-
const PreambleData *Preamble, llvm::StringRef Contents,
1756-
Position Pos, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
1757-
CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind) {
1758-
auto Offset = positionToOffset(Contents, Pos);
1748+
CodeCompleteResult codeComplete(PathRef FileName, Position Pos,
1749+
const PreambleData *Preamble,
1750+
const ParseInputs &ParseInput,
1751+
CodeCompleteOptions Opts,
1752+
SpeculativeFuzzyFind *SpecFuzzyFind) {
1753+
auto Offset = positionToOffset(ParseInput.Contents, Pos);
17591754
if (!Offset) {
17601755
elog("Code completion position was invalid {0}", Offset.takeError());
17611756
return CodeCompleteResult();
@@ -1764,21 +1759,18 @@ codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
17641759
FileName, Preamble ? Preamble->Includes : IncludeStructure(),
17651760
SpecFuzzyFind, Opts);
17661761
return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
1767-
? std::move(Flow).runWithoutSema(Contents, *Offset, VFS)
1768-
: std::move(Flow).run({FileName, Command, *Preamble,
1762+
? std::move(Flow).runWithoutSema(ParseInput.Contents, *Offset,
1763+
ParseInput.FS)
1764+
: std::move(Flow).run({FileName, *Offset, *Preamble,
17691765
// We want to serve code completions with
17701766
// low latency, so don't bother patching.
1771-
/*PreamblePatch=*/llvm::None, Contents,
1772-
*Offset, VFS});
1767+
/*PreamblePatch=*/llvm::None, ParseInput});
17731768
}
17741769

1775-
SignatureHelp signatureHelp(PathRef FileName,
1776-
const tooling::CompileCommand &Command,
1770+
SignatureHelp signatureHelp(PathRef FileName, Position Pos,
17771771
const PreambleData &Preamble,
1778-
llvm::StringRef Contents, Position Pos,
1779-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
1780-
const SymbolIndex *Index) {
1781-
auto Offset = positionToOffset(Contents, Pos);
1772+
const ParseInputs &ParseInput) {
1773+
auto Offset = positionToOffset(ParseInput.Contents, Pos);
17821774
if (!Offset) {
17831775
elog("Signature help position was invalid {0}", Offset.takeError());
17841776
return SignatureHelp();
@@ -1789,16 +1781,12 @@ SignatureHelp signatureHelp(PathRef FileName,
17891781
Options.IncludeMacros = false;
17901782
Options.IncludeCodePatterns = false;
17911783
Options.IncludeBriefComments = false;
1792-
1793-
ParseInputs PI;
1794-
PI.CompileCommand = Command;
1795-
PI.Contents = Contents.str();
1796-
PI.FS = std::move(VFS);
17971784
semaCodeComplete(
1798-
std::make_unique<SignatureHelpCollector>(Options, Index, Result), Options,
1799-
{FileName, Command, Preamble,
1800-
PreamblePatch::create(FileName, PI, Preamble), Contents, *Offset,
1801-
std::move(PI.FS)});
1785+
std::make_unique<SignatureHelpCollector>(Options, ParseInput.Index,
1786+
Result),
1787+
Options,
1788+
{FileName, *Offset, Preamble,
1789+
PreamblePatch::create(FileName, ParseInput, Preamble), ParseInput});
18021790
return Result;
18031791
}
18041792

Diff for: clang-tools-extra/clangd/CodeComplete.h

+6-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
1616
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
1717

18+
#include "Compiler.h"
1819
#include "Headers.h"
1920
#include "Protocol.h"
2021
#include "Quality.h"
@@ -270,21 +271,16 @@ struct SpeculativeFuzzyFind {
270271
/// the speculative result is used by code completion (e.g. speculation failed),
271272
/// the speculative result is not consumed, and `SpecFuzzyFind` is only
272273
/// destroyed when the async request finishes.
273-
CodeCompleteResult codeComplete(PathRef FileName,
274-
const tooling::CompileCommand &Command,
274+
CodeCompleteResult codeComplete(PathRef FileName, Position Pos,
275275
const PreambleData *Preamble,
276-
StringRef Contents, Position Pos,
277-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
276+
const ParseInputs &ParseInput,
278277
CodeCompleteOptions Opts,
279278
SpeculativeFuzzyFind *SpecFuzzyFind = nullptr);
280279

281280
/// Get signature help at a specified \p Pos in \p FileName.
282-
SignatureHelp signatureHelp(PathRef FileName,
283-
const tooling::CompileCommand &Command,
284-
const PreambleData &Preamble, StringRef Contents,
285-
Position Pos,
286-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
287-
const SymbolIndex *Index);
281+
SignatureHelp signatureHelp(PathRef FileName, Position Pos,
282+
const PreambleData &Preamble,
283+
const ParseInputs &ParseInput);
288284

289285
// For index-based completion, we only consider:
290286
// * symbols in namespaces or translation unit scopes (e.g. no class

Diff for: clang-tools-extra/clangd/Compiler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct ParseInputs {
5454
bool ForceRebuild = false;
5555
// Used to recover from diagnostics (e.g. find missing includes for symbol).
5656
const SymbolIndex *Index = nullptr;
57-
ParseOptions Opts;
57+
ParseOptions Opts = ParseOptions();
5858
};
5959

6060
/// Builds compiler invocation that could be used to build AST or preamble.

Diff for: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,11 @@ CodeCompleteResult completions(const TestTU &TU, Position Point,
117117
}
118118
auto Preamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
119119
/*InMemory=*/true, /*Callback=*/nullptr);
120-
return codeComplete(testPath(TU.Filename), Inputs.CompileCommand,
121-
Preamble.get(), TU.Code, Point, Inputs.FS, Opts);
120+
ParseInputs ParseInput{Inputs.CompileCommand, Inputs.FS, TU.Code};
121+
ParseInput.Opts.BuildRecoveryAST = true;
122+
ParseInput.Opts.PreserveRecoveryASTType = true;
123+
return codeComplete(testPath(TU.Filename), Point, Preamble.get(), ParseInput,
124+
Opts);
122125
}
123126

124127
// Runs code completion.
@@ -148,8 +151,10 @@ CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
148151

149152
MockFSProvider FS;
150153
Annotations Test(Text);
151-
return codeComplete(FilePath, tooling::CompileCommand(), /*Preamble=*/nullptr,
152-
Test.code(), Test.point(), FS.getFileSystem(), Opts);
154+
ParseInputs ParseInput{tooling::CompileCommand(), FS.getFileSystem(),
155+
Test.code().str()};
156+
return codeComplete(FilePath, Test.point(), /*Preamble=*/nullptr, ParseInput,
157+
Opts);
153158
}
154159

155160
Symbol withReferences(int N, Symbol S) {
@@ -753,8 +758,7 @@ TEST(CompletionTest, CompletionInPreamble) {
753758
EXPECT_THAT(Results, ElementsAre(Named("ifndef")));
754759
}
755760

756-
// FIXME: enable it.
757-
TEST(CompletionTest, DISABLED_CompletionRecoveryASTType) {
761+
TEST(CompletionTest, CompletionRecoveryASTType) {
758762
auto Results = completions(R"cpp(
759763
struct S { int member; };
760764
S overloaded(int);
@@ -1067,8 +1071,11 @@ SignatureHelp signatures(llvm::StringRef Text, Position Point,
10671071
ADD_FAILURE() << "Couldn't build Preamble";
10681072
return {};
10691073
}
1070-
return signatureHelp(testPath(TU.Filename), Inputs.CompileCommand, *Preamble,
1071-
Text, Point, Inputs.FS, Index.get());
1074+
ParseInputs ParseInput{Inputs.CompileCommand, Inputs.FS, Text.str()};
1075+
ParseInput.Index = Index.get();
1076+
ParseInput.Opts.BuildRecoveryAST = true;
1077+
ParseInput.Opts.PreserveRecoveryASTType = true;
1078+
return signatureHelp(testPath(TU.Filename), Point, *Preamble, ParseInput);
10721079
}
10731080

10741081
SignatureHelp signatures(llvm::StringRef Text,
@@ -1219,9 +1226,10 @@ TEST(SignatureHelpTest, StalePreamble) {
12191226
void bar() { foo(^2); })cpp");
12201227
TU.Code = Test.code().str();
12211228
Inputs = TU.inputs();
1222-
auto Results =
1223-
signatureHelp(testPath(TU.Filename), Inputs.CompileCommand,
1224-
*EmptyPreamble, TU.Code, Test.point(), Inputs.FS, nullptr);
1229+
1230+
ParseInputs ParseInput{Inputs.CompileCommand, Inputs.FS, TU.Code};
1231+
auto Results = signatureHelp(testPath(TU.Filename), Test.point(),
1232+
*EmptyPreamble, ParseInput);
12251233
EXPECT_THAT(Results.signatures, ElementsAre(Sig("foo([[int x]]) -> int")));
12261234
EXPECT_EQ(0, Results.activeSignature);
12271235
EXPECT_EQ(0, Results.activeParameter);

0 commit comments

Comments
 (0)