Skip to content

Commit 22ba61b

Browse files
committed
Reapply "[CodeComplete] Teach code completion engine to recognize and manifest @recommended and @recommendedover." after fixing a linux failure. (thanks, Dmitri)
1 parent 8858503 commit 22ba61b

File tree

8 files changed

+193
-59
lines changed

8 files changed

+193
-59
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ class CodeCompletionResult {
497497
StringRef ModuleName;
498498
StringRef BriefDocComment;
499499
ArrayRef<StringRef> AssociatedUSRs;
500-
ArrayRef<StringRef> Keywords;
500+
ArrayRef<std::pair<StringRef, StringRef>> DocWords;
501501
unsigned TypeDistance : 3;
502502

503503
public:
@@ -558,14 +558,14 @@ class CodeCompletionResult {
558558
const Decl *AssociatedDecl, StringRef ModuleName,
559559
bool NotRecommended, StringRef BriefDocComment,
560560
ArrayRef<StringRef> AssociatedUSRs,
561-
ArrayRef<StringRef> Keywords,
561+
ArrayRef<std::pair<StringRef, StringRef>> DocWords,
562562
enum ExpectedTypeRelation TypeDistance)
563563
: Kind(ResultKind::Declaration),
564564
SemanticContext(unsigned(SemanticContext)),
565565
NotRecommended(NotRecommended), NumBytesToErase(NumBytesToErase),
566566
CompletionString(CompletionString), ModuleName(ModuleName),
567567
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
568-
Keywords(Keywords), TypeDistance(TypeDistance) {
568+
DocWords(DocWords), TypeDistance(TypeDistance) {
569569
assert(AssociatedDecl && "should have a decl");
570570
AssociatedKind = unsigned(getCodeCompletionDeclKind(AssociatedDecl));
571571
assert(CompletionString);
@@ -578,13 +578,13 @@ class CodeCompletionResult {
578578
CodeCompletionDeclKind DeclKind, StringRef ModuleName,
579579
bool NotRecommended, StringRef BriefDocComment,
580580
ArrayRef<StringRef> AssociatedUSRs,
581-
ArrayRef<StringRef> Keywords)
581+
ArrayRef<std::pair<StringRef, StringRef>> DocWords)
582582
: Kind(ResultKind::Declaration),
583583
SemanticContext(unsigned(SemanticContext)),
584584
NotRecommended(NotRecommended), NumBytesToErase(NumBytesToErase),
585585
CompletionString(CompletionString), ModuleName(ModuleName),
586586
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
587-
Keywords(Keywords) {
587+
DocWords(DocWords) {
588588
AssociatedKind = static_cast<unsigned>(DeclKind);
589589
assert(CompletionString);
590590
TypeDistance = ExpectedTypeRelation::Unrelated;
@@ -650,8 +650,8 @@ class CodeCompletionResult {
650650
return AssociatedUSRs;
651651
}
652652

653-
ArrayRef<StringRef> getDeclKeywords() const {
654-
return Keywords;
653+
ArrayRef<std::pair<StringRef, StringRef>> getDeclKeywords() const {
654+
return DocWords;
655655
}
656656

657657
/// Print a debug representation of the code completion result to \p OS.

lib/IDE/CodeCompletion.cpp

Lines changed: 134 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,55 @@ using namespace ide;
4646

4747
namespace clang {
4848
namespace comments {
49+
50+
enum CodeCompletionCommandKind {
51+
none,
52+
keyword,
53+
recommended,
54+
recommendedover,
55+
};
56+
57+
typedef std::vector<std::pair<StringRef, StringRef>> CommandWordsPairs;
58+
59+
class WordPairsArrangedViewer {
60+
ArrayRef<std::pair<StringRef, StringRef>> Content;
61+
std::vector<StringRef> ViewedText;
62+
std::vector<StringRef> Words;
63+
StringRef Key;
64+
65+
bool isKeyViewed(StringRef K) {
66+
return std::find(ViewedText.begin(), ViewedText.end(), K) != ViewedText.end();
67+
}
68+
69+
public:
70+
WordPairsArrangedViewer(ArrayRef<std::pair<StringRef, StringRef>> Content):
71+
Content(Content) {}
72+
73+
bool hasNext() {
74+
Words.clear();
75+
bool Found = false;
76+
for (auto P : Content) {
77+
if (!Found && !isKeyViewed(P.first)) {
78+
Key = P.first;
79+
Found = true;
80+
}
81+
if (Found && P.first == Key)
82+
Words.push_back(P.second);
83+
}
84+
return Found;
85+
}
86+
87+
std::pair<StringRef, ArrayRef<StringRef>> next() {
88+
bool HasNext = hasNext();
89+
assert(HasNext && "Have no more data.");
90+
ViewedText.push_back(Key);
91+
return std::make_pair(Key, llvm::makeArrayRef(Words));
92+
}
93+
};
94+
4995
class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor> {
50-
std::vector<StringRef> &Keywords;
96+
CommandWordsPairs &Words;
5197
const CommandTraits &Traits;
52-
std::string Keyword = "keyword";
5398
std::vector<const Comment *> Parents;
5499

55100
void visitChildren(const Comment* C) {
@@ -59,9 +104,33 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
59104
Parents.pop_back();
60105
}
61106

107+
StringRef getCommnadName(CodeCompletionCommandKind Kind) {
108+
#define CHECK_CASE(KIND) \
109+
if (CodeCompletionCommandKind::KIND == Kind) { \
110+
static std::string Name(#KIND); \
111+
return Name; \
112+
}
113+
CHECK_CASE(keyword)
114+
CHECK_CASE(recommended)
115+
CHECK_CASE(recommendedover)
116+
#undef CHECK_CASE
117+
llvm_unreachable("Can not handle this Kind.");
118+
}
119+
120+
CodeCompletionCommandKind getCommandKind(StringRef Command) {
121+
#define CHECK_CASE(KIND) \
122+
if (Command == #KIND) \
123+
return CodeCompletionCommandKind::KIND;
124+
CHECK_CASE(keyword);
125+
CHECK_CASE(recommended);
126+
CHECK_CASE(recommendedover);
127+
#undef CHECK_CASE
128+
return CodeCompletionCommandKind::none;
129+
}
130+
62131
public:
63-
ClangCommentExtractor(std::vector<StringRef> &Keywords,
64-
const CommandTraits &Traits) : Keywords(Keywords),
132+
ClangCommentExtractor(CommandWordsPairs &Words,
133+
const CommandTraits &Traits) : Words(Words),
65134
Traits(Traits) {}
66135
#define CHILD_VISIT(NAME) \
67136
void visit##NAME(const NAME *C) {\
@@ -73,7 +142,8 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
73142

74143
void visitInlineCommandComment(const InlineCommandComment *C) {
75144
auto Command = C->getCommandName(Traits);
76-
if (Command != Keyword)
145+
auto CommandKind = getCommandKind(Command);
146+
if (CommandKind == CodeCompletionCommandKind::none)
77147
return;
78148
auto &Parent = Parents.back();
79149
for (auto CIT = std::find(Parent->child_begin(), Parent->child_end(), C) + 1;
@@ -84,7 +154,7 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
84154
auto Pair = Text.split(',');
85155
auto Key = Pair.first.trim();
86156
if (!Key.empty())
87-
Keywords.push_back(Key);
157+
Words.push_back(std::make_pair(getCommnadName(CommandKind), Key));
88158
Text = Pair.second;
89159
} while (!Text.empty());
90160
} else
@@ -93,13 +163,27 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
93163
}
94164
};
95165

166+
bool containsInterestedWords(StringRef Content) {
167+
do {
168+
Content = Content.split('@').second;
169+
#define CHECK_CASE(KIND) \
170+
if (Content.startswith(#KIND)) \
171+
return true;
172+
CHECK_CASE(keyword)
173+
CHECK_CASE(recommended)
174+
CHECK_CASE(recommendedover)
175+
#undef CHECK_CASE
176+
} while(!Content.empty());
177+
return false;
178+
}
179+
96180
void getClangDocKeyword(ClangImporter &Importer, const Decl *D,
97-
std::vector<StringRef> &Keywords) {
98-
ClangCommentExtractor Extractor(Keywords, Importer.getClangASTContext().
181+
CommandWordsPairs &Words) {
182+
ClangCommentExtractor Extractor(Words, Importer.getClangASTContext().
99183
getCommentCommandTraits());
100184
if (auto RC = Importer.getClangASTContext().getRawCommentForAnyRedecl(D)) {
101185
auto RT = RC->getRawText(Importer.getClangASTContext().getSourceManager());
102-
if (RT.find("@keyword") != StringRef::npos) {
186+
if (containsInterestedWords(RT)) {
103187
FullComment* Comment = Importer.getClangASTContext().
104188
getLocalCommentForDeclUncached(D);
105189
Extractor.visit(Comment);
@@ -533,10 +617,14 @@ void CodeCompletionResult::print(raw_ostream &OS) const {
533617
break;
534618
}
535619

536-
if (!Keywords.empty()) {
537-
Prefix.append("/Keywords[");
620+
for (clang::comments::WordPairsArrangedViewer Viewer(DocWords);
621+
Viewer.hasNext();) {
622+
auto Pair = Viewer.next();
623+
Prefix.append("/");
624+
Prefix.append(Pair.first);
625+
Prefix.append("[");
538626
StringRef Sep = ", ";
539-
for (auto KW : Keywords) {
627+
for (auto KW : Pair.second) {
540628
Prefix.append(KW);
541629
Prefix.append(Sep);
542630
}
@@ -571,6 +659,18 @@ static ArrayRef<StringRef> copyStringArray(llvm::BumpPtrAllocator &Allocator,
571659
return llvm::makeArrayRef(Buff, Arr.size());
572660
}
573661

662+
static ArrayRef<std::pair<StringRef, StringRef>> copyStringPairArray(
663+
llvm::BumpPtrAllocator &Allocator,
664+
ArrayRef<std::pair<StringRef, StringRef>> Arr) {
665+
std::pair<StringRef, StringRef> *Buff = Allocator.Allocate<std::pair<StringRef,
666+
StringRef>>(Arr.size());
667+
for (unsigned I = 0; I < Arr.size(); ++I) {
668+
Buff[I].first = Arr[I].first;
669+
Buff[I].second = Arr[I].second;
670+
}
671+
return llvm::makeArrayRef(Buff, Arr.size());
672+
}
673+
574674
void CodeCompletionResultBuilder::addChunkWithText(
575675
CodeCompletionString::Chunk::ChunkKind Kind, StringRef Text) {
576676
addChunkWithTextNoCopy(Kind, copyString(*Sink.Allocator, Text));
@@ -734,7 +834,7 @@ CodeCompletionResult *CodeCompletionResultBuilder::takeResult() {
734834
SemanticContext, NumBytesToErase, CCS, AssociatedDecl, ModuleName,
735835
/*NotRecommended=*/false, copyString(*Sink.Allocator, BriefComment),
736836
copyAssociatedUSRs(*Sink.Allocator, AssociatedDecl),
737-
copyStringArray(*Sink.Allocator, DeclKeywords), typeRelation);
837+
copyStringPairArray(*Sink.Allocator, CommentWords), typeRelation);
738838
}
739839

740840
case CodeCompletionResult::ResultKind::Keyword:
@@ -1310,11 +1410,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
13101410
}
13111411

13121412
void setClangDeclKeywords(const ValueDecl *VD,
1413+
clang::comments::CommandWordsPairs &Pairs,
13131414
CodeCompletionResultBuilder &Builder) {
13141415
if (auto *CD = VD->getClangDecl()) {
1315-
std::vector<StringRef> Keywords;
1316-
clang::comments::getClangDocKeyword(*Importer, CD, Keywords);
1317-
Builder.addDeclKeywords(Keywords);
1416+
clang::comments::getClangDocKeyword(*Importer, CD, Pairs);
1417+
Builder.addDeclDocCommentWords(Pairs);
13181418
}
13191419
}
13201420

@@ -1609,14 +1709,15 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
16091709
"name lookup bug -- can not see an instance variable "
16101710
"in a static function");
16111711

1712+
clang::comments::CommandWordsPairs Pairs;
16121713
CodeCompletionResultBuilder Builder(
16131714
Sink,
16141715
CodeCompletionResult::ResultKind::Declaration,
16151716
getSemanticContext(VD, Reason), ExpectedTypes);
16161717
Builder.setAssociatedDecl(VD);
16171718
addLeadingDot(Builder);
16181719
Builder.addTextChunk(Name);
1619-
setClangDeclKeywords(VD, Builder);
1720+
setClangDeclKeywords(VD, Pairs, Builder);
16201721
// Add a type annotation.
16211722
Type VarType = getTypeOfMember(VD);
16221723
if (VD->getName() == Ctx.Id_self) {
@@ -1913,10 +2014,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19132014

19142015
// Add the method, possibly including any default arguments.
19152016
auto addMethodImpl = [&](bool includeDefaultArgs = true) {
2017+
clang::comments::CommandWordsPairs Pairs;
19162018
CodeCompletionResultBuilder Builder(
19172019
Sink, CodeCompletionResult::ResultKind::Declaration,
19182020
getSemanticContext(FD, Reason), ExpectedTypes);
1919-
setClangDeclKeywords(FD, Builder);
2021+
setClangDeclKeywords(FD, Pairs, Builder);
19202022
Builder.setAssociatedDecl(FD);
19212023
addLeadingDot(Builder);
19222024
Builder.addTextChunk(Name);
@@ -2008,10 +2110,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
20082110

20092111
// Add the constructor, possibly including any default arguments.
20102112
auto addConstructorImpl = [&](bool includeDefaultArgs = true) {
2113+
clang::comments::CommandWordsPairs Pairs;
20112114
CodeCompletionResultBuilder Builder(
20122115
Sink, CodeCompletionResult::ResultKind::Declaration,
20132116
getSemanticContext(CD, Reason), ExpectedTypes);
2014-
setClangDeclKeywords(CD, Builder);
2117+
setClangDeclKeywords(CD, Pairs, Builder);
20152118
Builder.setAssociatedDecl(CD);
20162119
if (needInit) {
20172120
assert(addName.empty());
@@ -2080,12 +2183,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
20802183

20812184
void addSubscriptCall(const SubscriptDecl *SD, DeclVisibilityKind Reason) {
20822185
assert(!HaveDot && "can not add a subscript after a dot");
2186+
clang::comments::CommandWordsPairs Pairs;
20832187
CodeCompletionResultBuilder Builder(
20842188
Sink,
20852189
CodeCompletionResult::ResultKind::Declaration,
20862190
getSemanticContext(SD, Reason), ExpectedTypes);
20872191
Builder.setAssociatedDecl(SD);
2088-
setClangDeclKeywords(SD, Builder);
2192+
setClangDeclKeywords(SD, Pairs, Builder);
20892193
Builder.addLeftBracket();
20902194
addPatternParameters(Builder, SD->getIndices());
20912195
Builder.addRightBracket();
@@ -2102,24 +2206,26 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
21022206

21032207
void addNominalTypeRef(const NominalTypeDecl *NTD,
21042208
DeclVisibilityKind Reason) {
2209+
clang::comments::CommandWordsPairs Pairs;
21052210
CodeCompletionResultBuilder Builder(
21062211
Sink,
21072212
CodeCompletionResult::ResultKind::Declaration,
21082213
getSemanticContext(NTD, Reason), ExpectedTypes);
21092214
Builder.setAssociatedDecl(NTD);
2110-
setClangDeclKeywords(NTD, Builder);
2215+
setClangDeclKeywords(NTD, Pairs, Builder);
21112216
addLeadingDot(Builder);
21122217
Builder.addTextChunk(NTD->getName().str());
21132218
addTypeAnnotation(Builder, NTD->getDeclaredType());
21142219
}
21152220

21162221
void addTypeAliasRef(const TypeAliasDecl *TAD, DeclVisibilityKind Reason) {
2222+
clang::comments::CommandWordsPairs Pairs;
21172223
CodeCompletionResultBuilder Builder(
21182224
Sink,
21192225
CodeCompletionResult::ResultKind::Declaration,
21202226
getSemanticContext(TAD, Reason), ExpectedTypes);
21212227
Builder.setAssociatedDecl(TAD);
2122-
setClangDeclKeywords(TAD, Builder);
2228+
setClangDeclKeywords(TAD, Pairs, Builder);
21232229
addLeadingDot(Builder);
21242230
Builder.addTextChunk(TAD->getName().str());
21252231
if (TAD->hasUnderlyingType() && !TAD->getUnderlyingType()->is<ErrorType>())
@@ -2131,11 +2237,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
21312237

21322238
void addGenericTypeParamRef(const GenericTypeParamDecl *GP,
21332239
DeclVisibilityKind Reason) {
2240+
clang::comments::CommandWordsPairs Pairs;
21342241
CodeCompletionResultBuilder Builder(
21352242
Sink,
21362243
CodeCompletionResult::ResultKind::Declaration,
21372244
getSemanticContext(GP, Reason), ExpectedTypes);
2138-
setClangDeclKeywords(GP, Builder);
2245+
setClangDeclKeywords(GP, Pairs, Builder);
21392246
Builder.setAssociatedDecl(GP);
21402247
addLeadingDot(Builder);
21412248
Builder.addTextChunk(GP->getName().str());
@@ -2144,11 +2251,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
21442251

21452252
void addAssociatedTypeRef(const AssociatedTypeDecl *AT,
21462253
DeclVisibilityKind Reason) {
2254+
clang::comments::CommandWordsPairs Pairs;
21472255
CodeCompletionResultBuilder Builder(
21482256
Sink,
21492257
CodeCompletionResult::ResultKind::Declaration,
21502258
getSemanticContext(AT, Reason), ExpectedTypes);
2151-
setClangDeclKeywords(AT, Builder);
2259+
setClangDeclKeywords(AT, Pairs, Builder);
21522260
Builder.setAssociatedDecl(AT);
21532261
addLeadingDot(Builder);
21542262
Builder.addTextChunk(AT->getName().str());
@@ -2161,14 +2269,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
21612269
bool HasTypeContext) {
21622270
if (!EED->hasName())
21632271
return;
2164-
2272+
clang::comments::CommandWordsPairs Pairs;
21652273
CodeCompletionResultBuilder Builder(
21662274
Sink,
21672275
CodeCompletionResult::ResultKind::Declaration,
21682276
HasTypeContext ? SemanticContextKind::ExpressionSpecific
21692277
: getSemanticContext(EED, Reason), ExpectedTypes);
21702278
Builder.setAssociatedDecl(EED);
2171-
setClangDeclKeywords(EED, Builder);
2279+
setClangDeclKeywords(EED, Pairs, Builder);
21722280
addLeadingDot(Builder);
21732281
Builder.addTextChunk(EED->getName().str());
21742282
if (EED->hasArgumentType())

0 commit comments

Comments
 (0)