Skip to content

Commit 1ac617b

Browse files
committed
Merge from 'master' to 'sycl-web' (#146)
CONFLICT (content): Merge conflict in clang/include/clang/Basic/LangOptions.h
2 parents eee749b + 4f1e9a1 commit 1ac617b

File tree

691 files changed

+13134
-4411
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

691 files changed

+13134
-4411
lines changed

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
528528
CCOpts.IncludeFixIts = Params.capabilities.CompletionFixes;
529529
if (!CCOpts.BundleOverloads.hasValue())
530530
CCOpts.BundleOverloads = Params.capabilities.HasSignatureHelp;
531+
CCOpts.DocumentationFormat =
532+
Params.capabilities.CompletionDocumentationFormat;
531533
DiagOpts.EmbedFixesInDiagnostics = Params.capabilities.DiagnosticFixes;
532534
DiagOpts.SendDiagnosticCategory = Params.capabilities.DiagnosticCategory;
533535
DiagOpts.EmitRelatedLocations =

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "FileDistance.h"
2727
#include "FuzzyMatch.h"
2828
#include "Headers.h"
29+
#include "Hover.h"
2930
#include "Preamble.h"
3031
#include "Protocol.h"
3132
#include "Quality.h"
@@ -371,12 +372,19 @@ struct CodeCompletionBuilder {
371372
S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix);
372373
S.ReturnType = std::string(C.IndexResult->ReturnType);
373374
}
374-
if (ExtractDocumentation && Completion.Documentation.empty()) {
375-
if (C.IndexResult)
376-
Completion.Documentation = std::string(C.IndexResult->Documentation);
377-
else if (C.SemaResult)
378-
Completion.Documentation = getDocComment(*ASTCtx, *C.SemaResult,
379-
/*CommentsFromHeader=*/false);
375+
if (ExtractDocumentation && !Completion.Documentation) {
376+
auto SetDoc = [&](llvm::StringRef Doc) {
377+
if (!Doc.empty()) {
378+
Completion.Documentation.emplace();
379+
parseDocumentation(Doc, *Completion.Documentation);
380+
}
381+
};
382+
if (C.IndexResult) {
383+
SetDoc(C.IndexResult->Documentation);
384+
} else if (C.SemaResult) {
385+
SetDoc(getDocComment(*ASTCtx, *C.SemaResult,
386+
/*CommentsFromHeader=*/false));
387+
}
380388
}
381389
}
382390

@@ -1816,6 +1824,21 @@ bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) {
18161824
return false;
18171825
}
18181826

1827+
// FIXME: find a home for this (that can depend on both markup and Protocol).
1828+
static MarkupContent renderDoc(const markup::Document &Doc, MarkupKind Kind) {
1829+
MarkupContent Result;
1830+
Result.kind = Kind;
1831+
switch (Kind) {
1832+
case MarkupKind::PlainText:
1833+
Result.value.append(Doc.asPlainText());
1834+
break;
1835+
case MarkupKind::Markdown:
1836+
Result.value.append(Doc.asMarkdown());
1837+
break;
1838+
}
1839+
return Result;
1840+
}
1841+
18191842
CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const {
18201843
CompletionItem LSP;
18211844
const auto *InsertInclude = Includes.empty() ? nullptr : &Includes[0];
@@ -1830,9 +1853,16 @@ CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const {
18301853
? std::string(llvm::formatv("[{0} overloads]", BundleSize))
18311854
: ReturnType;
18321855
LSP.deprecated = Deprecated;
1833-
if (InsertInclude)
1834-
LSP.detail += "\n" + InsertInclude->Header;
1835-
LSP.documentation = Documentation;
1856+
// Combine header information and documentation in LSP `documentation` field.
1857+
// This is not quite right semantically, but tends to display well in editors.
1858+
if (InsertInclude || Documentation) {
1859+
markup::Document Doc;
1860+
if (InsertInclude)
1861+
Doc.addParagraph().appendText("From ").appendCode(InsertInclude->Header);
1862+
if (Documentation)
1863+
Doc.append(*Documentation);
1864+
LSP.documentation = renderDoc(Doc, Opts.DocumentationFormat);
1865+
}
18361866
LSP.sortText = sortText(Score.Total, Name);
18371867
LSP.filterText = Name;
18381868
LSP.textEdit = {CompletionTokenRange, RequiredQualifier + Name};

clang-tools-extra/clangd/CodeComplete.h

Lines changed: 6 additions & 1 deletion
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 "FormattedString.h"
1819
#include "Headers.h"
1920
#include "Protocol.h"
2021
#include "Quality.h"
@@ -73,6 +74,9 @@ struct CodeCompleteOptions {
7374
/// If more results are available, we set CompletionList.isIncomplete.
7475
size_t Limit = 0;
7576

77+
/// Whether to present doc comments as plain-text or markdown.
78+
MarkupKind DocumentationFormat = MarkupKind::PlainText;
79+
7680
enum IncludeInsertion {
7781
IWYU,
7882
NeverInsert,
@@ -161,7 +165,8 @@ struct CodeCompletion {
161165
std::string SnippetSuffix;
162166
// Type to be displayed for this completion.
163167
std::string ReturnType;
164-
std::string Documentation;
168+
// The parsed documentation comment.
169+
llvm::Optional<markup::Document> Documentation;
165170
CompletionItemKind Kind = CompletionItemKind::Missing;
166171
// This completion item may represent several symbols that can be inserted in
167172
// the same way, such as function overloads. In this case BundleSize > 1, and

clang-tools-extra/clangd/FormattedString.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ class Ruler : public Block {
271271
OS << "\n---\n";
272272
}
273273
void renderPlainText(llvm::raw_ostream &OS) const override { OS << '\n'; }
274+
std::unique_ptr<Block> clone() const override {
275+
return std::make_unique<Ruler>(*this);
276+
}
274277
bool isRuler() const override { return true; }
275278
};
276279

@@ -287,6 +290,10 @@ class CodeBlock : public Block {
287290
OS << '\n' << Contents << "\n\n";
288291
}
289292

293+
std::unique_ptr<Block> clone() const override {
294+
return std::make_unique<CodeBlock>(*this);
295+
}
296+
290297
CodeBlock(std::string Contents, std::string Language)
291298
: Contents(std::move(Contents)), Language(std::move(Language)) {}
292299

@@ -358,10 +365,28 @@ void Paragraph::renderMarkdown(llvm::raw_ostream &OS) const {
358365
OS << " \n";
359366
}
360367

368+
std::unique_ptr<Block> Paragraph::clone() const {
369+
return std::make_unique<Paragraph>(*this);
370+
}
371+
372+
/// Choose a marker to delimit `Text` from a prioritized list of options.
373+
/// This is more readable than escaping for plain-text.
374+
llvm::StringRef chooseMarker(llvm::ArrayRef<llvm::StringRef> Options,
375+
llvm::StringRef Text) {
376+
// Prefer a delimiter whose characters don't appear in the text.
377+
for (llvm::StringRef S : Options)
378+
if (Text.find_first_of(S) == llvm::StringRef::npos)
379+
return S;
380+
return Options.front();
381+
}
382+
361383
void Paragraph::renderPlainText(llvm::raw_ostream &OS) const {
362384
llvm::StringRef Sep = "";
363385
for (auto &C : Chunks) {
364-
OS << Sep << C.Contents;
386+
llvm::StringRef Marker = "";
387+
if (C.Preserve && C.Kind == Chunk::InlineCode)
388+
Marker = chooseMarker({"`", "'", "\""}, C.Contents);
389+
OS << Sep << Marker << C.Contents << Marker;
365390
Sep = " ";
366391
}
367392
OS << '\n';
@@ -396,22 +421,39 @@ Paragraph &Paragraph::appendText(llvm::StringRef Text) {
396421
return *this;
397422
}
398423

399-
Paragraph &Paragraph::appendCode(llvm::StringRef Code) {
424+
Paragraph &Paragraph::appendCode(llvm::StringRef Code, bool Preserve) {
400425
std::string Norm = canonicalizeSpaces(std::move(Code));
401426
if (Norm.empty())
402427
return *this;
403428
Chunks.emplace_back();
404429
Chunk &C = Chunks.back();
405430
C.Contents = std::move(Norm);
406431
C.Kind = Chunk::InlineCode;
432+
C.Preserve = Preserve;
407433
return *this;
408434
}
409435

436+
std::unique_ptr<Block> BulletList::clone() const {
437+
return std::make_unique<BulletList>(*this);
438+
}
439+
410440
class Document &BulletList::addItem() {
411441
Items.emplace_back();
412442
return Items.back();
413443
}
414444

445+
Document &Document::operator=(const Document &Other) {
446+
Children.clear();
447+
for (const auto &C : Other.Children)
448+
Children.push_back(C->clone());
449+
return *this;
450+
}
451+
452+
void Document::append(Document Other) {
453+
std::move(Other.Children.begin(), Other.Children.end(),
454+
std::back_inserter(Children));
455+
}
456+
415457
Paragraph &Document::addParagraph() {
416458
Children.push_back(std::make_unique<Paragraph>());
417459
return *static_cast<Paragraph *>(Children.back().get());

clang-tools-extra/clangd/FormattedString.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Block {
3030
public:
3131
virtual void renderMarkdown(llvm::raw_ostream &OS) const = 0;
3232
virtual void renderPlainText(llvm::raw_ostream &OS) const = 0;
33+
virtual std::unique_ptr<Block> clone() const = 0;
3334
std::string asMarkdown() const;
3435
std::string asPlainText() const;
3536

@@ -44,22 +45,24 @@ class Paragraph : public Block {
4445
public:
4546
void renderMarkdown(llvm::raw_ostream &OS) const override;
4647
void renderPlainText(llvm::raw_ostream &OS) const override;
48+
std::unique_ptr<Block> clone() const override;
4749

4850
/// Append plain text to the end of the string.
4951
Paragraph &appendText(llvm::StringRef Text);
5052

5153
/// Append inline code, this translates to the ` block in markdown.
52-
Paragraph &appendCode(llvm::StringRef Code);
54+
/// \p Preserve indicates the code span must be apparent even in plaintext.
55+
Paragraph &appendCode(llvm::StringRef Code, bool Preserve = false);
5356

5457
private:
5558
struct Chunk {
5659
enum {
5760
PlainText,
5861
InlineCode,
5962
} Kind = PlainText;
63+
// Preserve chunk markers in plaintext.
64+
bool Preserve = false;
6065
std::string Contents;
61-
/// Language for code block chunks. Ignored for other chunks.
62-
std::string Language;
6366
};
6467
std::vector<Chunk> Chunks;
6568
};
@@ -70,6 +73,7 @@ class BulletList : public Block {
7073
public:
7174
void renderMarkdown(llvm::raw_ostream &OS) const override;
7275
void renderPlainText(llvm::raw_ostream &OS) const override;
76+
std::unique_ptr<Block> clone() const override;
7377

7478
class Document &addItem();
7579

@@ -81,6 +85,14 @@ class BulletList : public Block {
8185
/// markdown and plaintext.
8286
class Document {
8387
public:
88+
Document() = default;
89+
Document(const Document &Other) { *this = Other; }
90+
Document &operator=(const Document &);
91+
Document(Document &&) = default;
92+
Document &operator=(Document &&) = default;
93+
94+
void append(Document Other);
95+
8496
/// Adds a semantical block that will be separate from others.
8597
Paragraph &addParagraph();
8698
/// Inserts a horizontal separator to the document.

clang-tools-extra/clangd/Hover.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ bool isHardLineBreakIndicator(llvm::StringRef Rest) {
648648
}
649649

650650
bool isHardLineBreakAfter(llvm::StringRef Line, llvm::StringRef Rest) {
651+
// Should we also consider whether Line is short?
651652
return punctuationIndicatesLineBreak(Line) || isHardLineBreakIndicator(Rest);
652653
}
653654

@@ -876,7 +877,7 @@ void parseDocumentationLine(llvm::StringRef Line, markup::Paragraph &Out) {
876877
case '`':
877878
if (auto Range = getBacktickQuoteRange(Line, I)) {
878879
Out.appendText(Line.substr(0, I));
879-
Out.appendCode(Range->trim("`"));
880+
Out.appendCode(Range->trim("`"), /*Preserve=*/true);
880881
return parseDocumentationLine(Line.substr(I+Range->size()), Out);
881882
}
882883
break;

clang-tools-extra/clangd/Hover.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct HoverInfo {
8080
};
8181

8282
// Try to infer structure of a documentation comment (e.g. line breaks).
83+
// FIXME: move to another file so CodeComplete doesn't depend on Hover.
8384
void parseDocumentation(llvm::StringRef Input, markup::Document &Output);
8485

8586
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &);

clang-tools-extra/clangd/Protocol.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,12 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R) {
311311
if (auto *Item = Completion->getObject("completionItem")) {
312312
if (auto SnippetSupport = Item->getBoolean("snippetSupport"))
313313
R.CompletionSnippets = *SnippetSupport;
314+
if (auto DocumentationFormat = Item->getArray("documentationFormat")) {
315+
for (const auto &Format : *DocumentationFormat) {
316+
if (fromJSON(Format, R.CompletionDocumentationFormat))
317+
break;
318+
}
319+
}
314320
}
315321
if (auto *ItemKind = Completion->getObject("completionItemKind")) {
316322
if (auto *ValueSet = ItemKind->get("valueSet")) {
@@ -334,11 +340,8 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R) {
334340
if (auto *Hover = TextDocument->getObject("hover")) {
335341
if (auto *ContentFormat = Hover->getArray("contentFormat")) {
336342
for (const auto &Format : *ContentFormat) {
337-
MarkupKind K = MarkupKind::PlainText;
338-
if (fromJSON(Format, K)) {
339-
R.HoverContentFormat = K;
343+
if (fromJSON(Format, R.HoverContentFormat))
340344
break;
341-
}
342345
}
343346
}
344347
}
@@ -891,7 +894,7 @@ llvm::json::Value toJSON(const CompletionItem &CI) {
891894
Result["kind"] = static_cast<int>(CI.kind);
892895
if (!CI.detail.empty())
893896
Result["detail"] = CI.detail;
894-
if (!CI.documentation.empty())
897+
if (CI.documentation)
895898
Result["documentation"] = CI.documentation;
896899
if (!CI.sortText.empty())
897900
Result["sortText"] = CI.sortText;

clang-tools-extra/clangd/Protocol.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@ struct ClientCapabilities {
430430
/// textDocument.completion.completionItemKind.valueSet
431431
llvm::Optional<CompletionItemKindBitset> CompletionItemKinds;
432432

433+
/// The documentation format that should be used for textDocument/completion.
434+
/// textDocument.completion.completionItem.documentationFormat
435+
MarkupKind CompletionDocumentationFormat = MarkupKind::PlainText;
436+
433437
/// Client supports CodeAction return value for textDocument/codeAction.
434438
/// textDocument.codeAction.codeActionLiteralSupport.
435439
bool CodeActionStructure = false;
@@ -1105,7 +1109,7 @@ struct CompletionItem {
11051109
std::string detail;
11061110

11071111
/// A human-readable string that represents a doc-comment.
1108-
std::string documentation;
1112+
llvm::Optional<MarkupContent> documentation;
11091113

11101114
/// A string that should be used when comparing this item with other items.
11111115
/// When `falsy` the label is used.

0 commit comments

Comments
 (0)