Skip to content

Commit 5c60232

Browse files
author
iclsrc
committed
Merge from 'main' to 'sycl-web'
2 parents 588d525 + ca13f55 commit 5c60232

File tree

8 files changed

+105
-33
lines changed

8 files changed

+105
-33
lines changed

clang-tools-extra/clangd/ClangdLSPServer.cpp

+20-16
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
518518
if (Params.capabilities.WorkDoneProgress)
519519
BackgroundIndexProgressState = BackgroundIndexProgress::Empty;
520520
BackgroundIndexSkipCreate = Params.capabilities.ImplicitProgressCreation;
521+
Opts.ImplicitCancellation = !Params.capabilities.CancelsStaleRequests;
521522

522523
llvm::json::Object ServerCaps{
523524
{"textDocumentSync",
@@ -779,7 +780,7 @@ void ClangdLSPServer::onWorkspaceSymbol(
779780
const WorkspaceSymbolParams &Params,
780781
Callback<std::vector<SymbolInformation>> Reply) {
781782
Server->workspaceSymbols(
782-
Params.query, Opts.CodeComplete.Limit,
783+
Params.query, Params.limit.getValueOr(Opts.CodeComplete.Limit),
783784
[Reply = std::move(Reply),
784785
this](llvm::Expected<std::vector<SymbolInformation>> Items) mutable {
785786
if (!Items)
@@ -1030,21 +1031,24 @@ void ClangdLSPServer::onCompletion(const CompletionParams &Params,
10301031
vlog("ignored auto-triggered completion, preceding char did not match");
10311032
return Reply(CompletionList());
10321033
}
1033-
Server->codeComplete(
1034-
Params.textDocument.uri.file(), Params.position, Opts.CodeComplete,
1035-
[Reply = std::move(Reply),
1036-
this](llvm::Expected<CodeCompleteResult> List) mutable {
1037-
if (!List)
1038-
return Reply(List.takeError());
1039-
CompletionList LSPList;
1040-
LSPList.isIncomplete = List->HasMore;
1041-
for (const auto &R : List->Completions) {
1042-
CompletionItem C = R.render(Opts.CodeComplete);
1043-
C.kind = adjustKindToCapability(C.kind, SupportedCompletionItemKinds);
1044-
LSPList.items.push_back(std::move(C));
1045-
}
1046-
return Reply(std::move(LSPList));
1047-
});
1034+
auto Opts = this->Opts.CodeComplete;
1035+
if (Params.limit && *Params.limit >= 0)
1036+
Opts.Limit = *Params.limit;
1037+
Server->codeComplete(Params.textDocument.uri.file(), Params.position, Opts,
1038+
[Reply = std::move(Reply), Opts,
1039+
this](llvm::Expected<CodeCompleteResult> List) mutable {
1040+
if (!List)
1041+
return Reply(List.takeError());
1042+
CompletionList LSPList;
1043+
LSPList.isIncomplete = List->HasMore;
1044+
for (const auto &R : List->Completions) {
1045+
CompletionItem C = R.render(Opts);
1046+
C.kind = adjustKindToCapability(
1047+
C.kind, SupportedCompletionItemKinds);
1048+
LSPList.items.push_back(std::move(C));
1049+
}
1050+
return Reply(std::move(LSPList));
1051+
});
10481052
}
10491053

10501054
void ClangdLSPServer::onSignatureHelp(const TextDocumentPositionParams &Params,

clang-tools-extra/clangd/ClangdServer.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
150150
DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
151151
ClangTidyProvider(Opts.ClangTidyProvider),
152152
WorkspaceRoot(Opts.WorkspaceRoot),
153+
Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate
154+
: TUScheduler::NoInvalidation),
153155
DirtyFS(std::make_unique<DraftStoreFS>(TFS, DraftMgr)) {
154156
// Pass a callback into `WorkScheduler` to extract symbols from a newly
155157
// parsed file and rebuild the file index synchronously each time an AST
@@ -593,7 +595,7 @@ void ClangdServer::enumerateTweaks(
593595
};
594596

595597
WorkScheduler->runWithAST("EnumerateTweaks", File, std::move(Action),
596-
TUScheduler::InvalidateOnUpdate);
598+
Transient);
597599
}
598600

599601
void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
@@ -683,8 +685,7 @@ void ClangdServer::findDocumentHighlights(
683685
CB(clangd::findDocumentHighlights(InpAST->AST, Pos));
684686
};
685687

686-
WorkScheduler->runWithAST("Highlights", File, std::move(Action),
687-
TUScheduler::InvalidateOnUpdate);
688+
WorkScheduler->runWithAST("Highlights", File, std::move(Action), Transient);
688689
}
689690

690691
void ClangdServer::findHover(PathRef File, Position Pos,
@@ -698,8 +699,7 @@ void ClangdServer::findHover(PathRef File, Position Pos,
698699
CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
699700
};
700701

701-
WorkScheduler->runWithAST("Hover", File, std::move(Action),
702-
TUScheduler::InvalidateOnUpdate);
702+
WorkScheduler->runWithAST("Hover", File, std::move(Action), Transient);
703703
}
704704

705705
void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve,
@@ -771,7 +771,7 @@ void ClangdServer::documentSymbols(llvm::StringRef File,
771771
CB(clangd::getDocumentSymbols(InpAST->AST));
772772
};
773773
WorkScheduler->runWithAST("DocumentSymbols", File, std::move(Action),
774-
TUScheduler::InvalidateOnUpdate);
774+
Transient);
775775
}
776776

777777
void ClangdServer::foldingRanges(llvm::StringRef File,
@@ -783,7 +783,7 @@ void ClangdServer::foldingRanges(llvm::StringRef File,
783783
CB(clangd::getFoldingRanges(InpAST->AST));
784784
};
785785
WorkScheduler->runWithAST("FoldingRanges", File, std::move(Action),
786-
TUScheduler::InvalidateOnUpdate);
786+
Transient);
787787
}
788788

789789
void ClangdServer::findImplementations(
@@ -850,7 +850,7 @@ void ClangdServer::documentLinks(PathRef File,
850850
CB(clangd::getDocumentLinks(InpAST->AST));
851851
};
852852
WorkScheduler->runWithAST("DocumentLinks", File, std::move(Action),
853-
TUScheduler::InvalidateOnUpdate);
853+
Transient);
854854
}
855855

856856
void ClangdServer::semanticHighlights(
@@ -862,7 +862,7 @@ void ClangdServer::semanticHighlights(
862862
CB(clangd::getSemanticHighlightings(InpAST->AST));
863863
};
864864
WorkScheduler->runWithAST("SemanticHighlights", File, std::move(Action),
865-
TUScheduler::InvalidateOnUpdate);
865+
Transient);
866866
}
867867

868868
void ClangdServer::getAST(PathRef File, Range R,

clang-tools-extra/clangd/ClangdServer.h

+8
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ class ClangdServer {
146146
/*RebuildRatio=*/1,
147147
};
148148

149+
/// Cancel certain requests if the file changes before they begin running.
150+
/// This is useful for "transient" actions like enumerateTweaks that were
151+
/// likely implicitly generated, and avoids redundant work if clients forget
152+
/// to cancel. Clients that always cancel stale requests should clear this.
153+
bool ImplicitCancellation = true;
154+
149155
/// Clangd will execute compiler drivers matching one of these globs to
150156
/// fetch system include path.
151157
std::vector<std::string> QueryDriverGlobs;
@@ -391,6 +397,8 @@ class ClangdServer {
391397

392398
llvm::Optional<std::string> WorkspaceRoot;
393399
llvm::Optional<TUScheduler> WorkScheduler;
400+
// Invalidation policy used for actions that we assume are "transient".
401+
TUScheduler::ASTActionInvalidation Transient;
394402

395403
// Store of the current versions of the open documents.
396404
// Only written from the main thread (despite being threadsafe).

clang-tools-extra/clangd/Protocol.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R,
414414
if (auto Implicit = Window->getBoolean("implicitWorkDoneProgressCreate"))
415415
R.ImplicitProgressCreation = *Implicit;
416416
}
417+
if (auto *General = O->getObject("general")) {
418+
if (auto *StaleRequestSupport = General->getObject("staleRequestSupport")) {
419+
if (auto Cancel = StaleRequestSupport->getBoolean("cancel"))
420+
R.CancelsStaleRequests = *Cancel;
421+
}
422+
}
417423
if (auto *OffsetEncoding = O->get("offsetEncoding")) {
418424
R.offsetEncoding.emplace();
419425
if (!fromJSON(*OffsetEncoding, *R.offsetEncoding,
@@ -744,7 +750,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) {
744750
bool fromJSON(const llvm::json::Value &Params, WorkspaceSymbolParams &R,
745751
llvm::json::Path P) {
746752
llvm::json::ObjectMapper O(Params, P);
747-
return O && O.map("query", R.query);
753+
return O && O.map("query", R.query) &&
754+
mapOptOrNull(Params, "limit", R.limit, P);
748755
}
749756

750757
llvm::json::Value toJSON(const Command &C) {
@@ -845,7 +852,8 @@ bool fromJSON(const llvm::json::Value &Params, CompletionContext &R,
845852

846853
bool fromJSON(const llvm::json::Value &Params, CompletionParams &R,
847854
llvm::json::Path P) {
848-
if (!fromJSON(Params, static_cast<TextDocumentPositionParams &>(R), P))
855+
if (!fromJSON(Params, static_cast<TextDocumentPositionParams &>(R), P) ||
856+
!mapOptOrNull(Params, "limit", R.limit, P))
849857
return false;
850858
if (auto *Context = Params.getAsObject()->get("context"))
851859
return fromJSON(*Context, R.context, P.field("context"));

clang-tools-extra/clangd/Protocol.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ struct ClientCapabilities {
475475
/// window.implicitWorkDoneProgressCreate
476476
bool ImplicitProgressCreation = false;
477477

478+
/// Whether the client claims to cancel stale requests.
479+
/// general.staleRequestSupport.cancel
480+
bool CancelsStaleRequests = false;
481+
478482
/// Whether the client implementation supports a refresh request sent from the
479483
/// server to the client.
480484
bool SemanticTokenRefreshSupport = false;
@@ -1052,8 +1056,13 @@ bool operator==(const SymbolDetails &, const SymbolDetails &);
10521056

10531057
/// The parameters of a Workspace Symbol Request.
10541058
struct WorkspaceSymbolParams {
1055-
/// A non-empty query string
1059+
/// A query string to filter symbols by.
1060+
/// Clients may send an empty string here to request all the symbols.
10561061
std::string query;
1062+
1063+
/// Max results to return, overriding global default. 0 means no limit.
1064+
/// Clangd extension.
1065+
llvm::Optional<int> limit;
10571066
};
10581067
bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &,
10591068
llvm::json::Path);
@@ -1102,6 +1111,10 @@ bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path);
11021111

11031112
struct CompletionParams : TextDocumentPositionParams {
11041113
CompletionContext context;
1114+
1115+
/// Max results to return, overriding global default. 0 means no limit.
1116+
/// Clangd extension.
1117+
llvm::Optional<int> limit;
11051118
};
11061119
bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path);
11071120

clang-tools-extra/clangd/refactor/Rename.cpp

+28-4
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,17 @@
2222
#include "clang/AST/DeclTemplate.h"
2323
#include "clang/AST/ParentMapContext.h"
2424
#include "clang/AST/Stmt.h"
25+
#include "clang/Basic/CharInfo.h"
2526
#include "clang/Basic/LLVM.h"
2627
#include "clang/Basic/SourceLocation.h"
2728
#include "clang/Tooling/Syntax/Tokens.h"
2829
#include "llvm/ADT/None.h"
2930
#include "llvm/ADT/STLExtras.h"
31+
#include "llvm/ADT/StringExtras.h"
3032
#include "llvm/Support/Casting.h"
3133
#include "llvm/Support/Error.h"
3234
#include "llvm/Support/FormatVariadic.h"
35+
#include "llvm/Support/JSON.h"
3336
#include <algorithm>
3437

3538
namespace clang {
@@ -178,8 +181,7 @@ enum class ReasonToReject {
178181
UnsupportedSymbol,
179182
AmbiguousSymbol,
180183

181-
// name validation.
182-
RenameToKeywords,
184+
// name validation. FIXME: reconcile with InvalidName
183185
SameName,
184186
};
185187

@@ -241,8 +243,6 @@ llvm::Error makeError(ReasonToReject Reason) {
241243
return "symbol is not a supported kind (e.g. namespace, macro)";
242244
case ReasonToReject::AmbiguousSymbol:
243245
return "there are multiple symbols at the given location";
244-
case ReasonToReject::RenameToKeywords:
245-
return "the chosen name is a keyword";
246246
case ReasonToReject::SameName:
247247
return "new name is the same as the old name";
248248
}
@@ -437,6 +437,7 @@ struct InvalidName {
437437
enum Kind {
438438
Keywords,
439439
Conflict,
440+
BadIdentifier,
440441
};
441442
Kind K;
442443
std::string Details;
@@ -447,6 +448,8 @@ std::string toString(InvalidName::Kind K) {
447448
return "Keywords";
448449
case InvalidName::Conflict:
449450
return "Conflict";
451+
case InvalidName::BadIdentifier:
452+
return "BadIdentifier";
450453
}
451454
llvm_unreachable("unhandled InvalidName kind");
452455
}
@@ -459,12 +462,31 @@ llvm::Error makeError(InvalidName Reason) {
459462
Reason.Details);
460463
case InvalidName::Conflict:
461464
return llvm::formatv("conflict with the symbol in {0}", Reason.Details);
465+
case InvalidName::BadIdentifier:
466+
return llvm::formatv("the chosen name \"{0}\" is not a valid identifier",
467+
Reason.Details);
462468
}
463469
llvm_unreachable("unhandled InvalidName kind");
464470
};
465471
return error("invalid name: {0}", Message(Reason));
466472
}
467473

474+
static bool mayBeValidIdentifier(llvm::StringRef Ident) {
475+
assert(llvm::json::isUTF8(Ident));
476+
if (Ident.empty())
477+
return false;
478+
// We don't check all the rules for non-ascii characters (most are allowed).
479+
bool AllowDollar = true; // lenient
480+
if (llvm::isASCII(Ident.front()) &&
481+
!isIdentifierHead(Ident.front(), AllowDollar))
482+
return false;
483+
for (char C : Ident) {
484+
if (llvm::isASCII(C) && !isIdentifierBody(C, AllowDollar))
485+
return false;
486+
}
487+
return true;
488+
}
489+
468490
// Check if we can rename the given RenameDecl into NewName.
469491
// Return details if the rename would produce a conflict.
470492
llvm::Optional<InvalidName> checkName(const NamedDecl &RenameDecl,
@@ -476,6 +498,8 @@ llvm::Optional<InvalidName> checkName(const NamedDecl &RenameDecl,
476498
llvm::Optional<InvalidName> Result;
477499
if (isKeyword(NewName, ASTCtx.getLangOpts()))
478500
Result = InvalidName{InvalidName::Keywords, NewName.str()};
501+
else if (!mayBeValidIdentifier(NewName))
502+
Result = InvalidName{InvalidName::BadIdentifier, NewName.str()};
479503
else {
480504
// Name conflict detection.
481505
// Function conflicts are subtle (overloading), so ignore them.

clang-tools-extra/clangd/unittests/RenameTests.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,21 @@ TEST(RenameTest, PrepareRename) {
12401240
testing::HasSubstr("keyword"));
12411241
EXPECT_THAT(Tracer.takeMetric("rename_name_invalid", "Keywords"),
12421242
ElementsAre(1));
1243+
1244+
for (std::string BadIdent : {"foo!bar", "123foo", "😀@"}) {
1245+
Results = runPrepareRename(Server, FooCCPath, FooCC.point(),
1246+
/*NewName=*/BadIdent, {});
1247+
EXPECT_FALSE(Results);
1248+
EXPECT_THAT(llvm::toString(Results.takeError()),
1249+
testing::HasSubstr("identifier"));
1250+
EXPECT_THAT(Tracer.takeMetric("rename_name_invalid", "BadIdentifier"),
1251+
ElementsAre(1));
1252+
}
1253+
for (std::string GoodIdent : {"fooBar", "__foo$", "😀"}) {
1254+
Results = runPrepareRename(Server, FooCCPath, FooCC.point(),
1255+
/*NewName=*/GoodIdent, {});
1256+
EXPECT_TRUE(bool(Results));
1257+
}
12431258
}
12441259

12451260
TEST(CrossFileRenameTests, DirtyBuffer) {

llvm/cmake/modules/GetErrcMessages.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function(get_errc_messages outvar)
2929
${errc_test_code}
3030
RUN_OUTPUT_VARIABLE errc_result
3131
COMPILE_OUTPUT_VARIABLE errc_compile_errors)
32-
if (errc_compiled)
32+
if (errc_compiled AND "${errc_exit_code}" STREQUAL "0")
3333
set(${outvar} ${errc_result} PARENT_SCOPE)
3434
else()
3535
set(${outvar} "" PARENT_SCOPE)

0 commit comments

Comments
 (0)