@@ -46,10 +46,55 @@ using namespace ide;
46
46
47
47
namespace clang {
48
48
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
+
49
95
class ClangCommentExtractor : public ConstCommentVisitor <ClangCommentExtractor> {
50
- std::vector<StringRef> &Keywords ;
96
+ CommandWordsPairs &Words ;
51
97
const CommandTraits &Traits;
52
- std::string Keyword = " keyword" ;
53
98
std::vector<const Comment *> Parents;
54
99
55
100
void visitChildren (const Comment* C) {
@@ -59,9 +104,33 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
59
104
Parents.pop_back ();
60
105
}
61
106
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
+
62
131
public:
63
- ClangCommentExtractor (std::vector<StringRef> &Keywords ,
64
- const CommandTraits &Traits) : Keywords(Keywords ),
132
+ ClangCommentExtractor (CommandWordsPairs &Words ,
133
+ const CommandTraits &Traits) : Words(Words ),
65
134
Traits (Traits) {}
66
135
#define CHILD_VISIT (NAME ) \
67
136
void visit##NAME(const NAME *C) {\
@@ -73,7 +142,8 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
73
142
74
143
void visitInlineCommandComment (const InlineCommandComment *C) {
75
144
auto Command = C->getCommandName (Traits);
76
- if (Command != Keyword)
145
+ auto CommandKind = getCommandKind (Command);
146
+ if (CommandKind == CodeCompletionCommandKind::none)
77
147
return ;
78
148
auto &Parent = Parents.back ();
79
149
for (auto CIT = std::find (Parent->child_begin (), Parent->child_end (), C) + 1 ;
@@ -84,7 +154,7 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
84
154
auto Pair = Text.split (' ,' );
85
155
auto Key = Pair.first .trim ();
86
156
if (!Key.empty ())
87
- Keywords .push_back (Key);
157
+ Words .push_back (std::make_pair ( getCommnadName (CommandKind), Key) );
88
158
Text = Pair.second ;
89
159
} while (!Text.empty ());
90
160
} else
@@ -93,13 +163,27 @@ class ClangCommentExtractor : public ConstCommentVisitor<ClangCommentExtractor>
93
163
}
94
164
};
95
165
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
+
96
180
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 ().
99
183
getCommentCommandTraits ());
100
184
if (auto RC = Importer.getClangASTContext ().getRawCommentForAnyRedecl (D)) {
101
185
auto RT = RC->getRawText (Importer.getClangASTContext ().getSourceManager ());
102
- if (RT. find ( " @keyword " ) != StringRef::npos ) {
186
+ if (containsInterestedWords (RT) ) {
103
187
FullComment* Comment = Importer.getClangASTContext ().
104
188
getLocalCommentForDeclUncached (D);
105
189
Extractor.visit (Comment);
@@ -533,10 +617,14 @@ void CodeCompletionResult::print(raw_ostream &OS) const {
533
617
break ;
534
618
}
535
619
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 (" [" );
538
626
StringRef Sep = " , " ;
539
- for (auto KW : Keywords ) {
627
+ for (auto KW : Pair. second ) {
540
628
Prefix.append (KW);
541
629
Prefix.append (Sep);
542
630
}
@@ -571,6 +659,18 @@ static ArrayRef<StringRef> copyStringArray(llvm::BumpPtrAllocator &Allocator,
571
659
return llvm::makeArrayRef (Buff, Arr.size ());
572
660
}
573
661
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
+
574
674
void CodeCompletionResultBuilder::addChunkWithText (
575
675
CodeCompletionString::Chunk::ChunkKind Kind, StringRef Text) {
576
676
addChunkWithTextNoCopy (Kind, copyString (*Sink.Allocator , Text));
@@ -734,7 +834,7 @@ CodeCompletionResult *CodeCompletionResultBuilder::takeResult() {
734
834
SemanticContext, NumBytesToErase, CCS, AssociatedDecl, ModuleName,
735
835
/* NotRecommended=*/ false , copyString (*Sink.Allocator , BriefComment),
736
836
copyAssociatedUSRs (*Sink.Allocator , AssociatedDecl),
737
- copyStringArray (*Sink.Allocator , DeclKeywords ), typeRelation);
837
+ copyStringPairArray (*Sink.Allocator , CommentWords ), typeRelation);
738
838
}
739
839
740
840
case CodeCompletionResult::ResultKind::Keyword:
@@ -1310,11 +1410,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1310
1410
}
1311
1411
1312
1412
void setClangDeclKeywords (const ValueDecl *VD,
1413
+ clang::comments::CommandWordsPairs &Pairs,
1313
1414
CodeCompletionResultBuilder &Builder) {
1314
1415
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);
1318
1418
}
1319
1419
}
1320
1420
@@ -1609,14 +1709,15 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1609
1709
" name lookup bug -- can not see an instance variable "
1610
1710
" in a static function" );
1611
1711
1712
+ clang::comments::CommandWordsPairs Pairs;
1612
1713
CodeCompletionResultBuilder Builder (
1613
1714
Sink,
1614
1715
CodeCompletionResult::ResultKind::Declaration,
1615
1716
getSemanticContext (VD, Reason), ExpectedTypes);
1616
1717
Builder.setAssociatedDecl (VD);
1617
1718
addLeadingDot (Builder);
1618
1719
Builder.addTextChunk (Name);
1619
- setClangDeclKeywords (VD, Builder);
1720
+ setClangDeclKeywords (VD, Pairs, Builder);
1620
1721
// Add a type annotation.
1621
1722
Type VarType = getTypeOfMember (VD);
1622
1723
if (VD->getName () == Ctx.Id_self ) {
@@ -1913,10 +2014,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1913
2014
1914
2015
// Add the method, possibly including any default arguments.
1915
2016
auto addMethodImpl = [&](bool includeDefaultArgs = true ) {
2017
+ clang::comments::CommandWordsPairs Pairs;
1916
2018
CodeCompletionResultBuilder Builder (
1917
2019
Sink, CodeCompletionResult::ResultKind::Declaration,
1918
2020
getSemanticContext (FD, Reason), ExpectedTypes);
1919
- setClangDeclKeywords (FD, Builder);
2021
+ setClangDeclKeywords (FD, Pairs, Builder);
1920
2022
Builder.setAssociatedDecl (FD);
1921
2023
addLeadingDot (Builder);
1922
2024
Builder.addTextChunk (Name);
@@ -2008,10 +2110,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2008
2110
2009
2111
// Add the constructor, possibly including any default arguments.
2010
2112
auto addConstructorImpl = [&](bool includeDefaultArgs = true ) {
2113
+ clang::comments::CommandWordsPairs Pairs;
2011
2114
CodeCompletionResultBuilder Builder (
2012
2115
Sink, CodeCompletionResult::ResultKind::Declaration,
2013
2116
getSemanticContext (CD, Reason), ExpectedTypes);
2014
- setClangDeclKeywords (CD, Builder);
2117
+ setClangDeclKeywords (CD, Pairs, Builder);
2015
2118
Builder.setAssociatedDecl (CD);
2016
2119
if (needInit) {
2017
2120
assert (addName.empty ());
@@ -2080,12 +2183,13 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2080
2183
2081
2184
void addSubscriptCall (const SubscriptDecl *SD, DeclVisibilityKind Reason) {
2082
2185
assert (!HaveDot && " can not add a subscript after a dot" );
2186
+ clang::comments::CommandWordsPairs Pairs;
2083
2187
CodeCompletionResultBuilder Builder (
2084
2188
Sink,
2085
2189
CodeCompletionResult::ResultKind::Declaration,
2086
2190
getSemanticContext (SD, Reason), ExpectedTypes);
2087
2191
Builder.setAssociatedDecl (SD);
2088
- setClangDeclKeywords (SD, Builder);
2192
+ setClangDeclKeywords (SD, Pairs, Builder);
2089
2193
Builder.addLeftBracket ();
2090
2194
addPatternParameters (Builder, SD->getIndices ());
2091
2195
Builder.addRightBracket ();
@@ -2102,24 +2206,26 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2102
2206
2103
2207
void addNominalTypeRef (const NominalTypeDecl *NTD,
2104
2208
DeclVisibilityKind Reason) {
2209
+ clang::comments::CommandWordsPairs Pairs;
2105
2210
CodeCompletionResultBuilder Builder (
2106
2211
Sink,
2107
2212
CodeCompletionResult::ResultKind::Declaration,
2108
2213
getSemanticContext (NTD, Reason), ExpectedTypes);
2109
2214
Builder.setAssociatedDecl (NTD);
2110
- setClangDeclKeywords (NTD, Builder);
2215
+ setClangDeclKeywords (NTD, Pairs, Builder);
2111
2216
addLeadingDot (Builder);
2112
2217
Builder.addTextChunk (NTD->getName ().str ());
2113
2218
addTypeAnnotation (Builder, NTD->getDeclaredType ());
2114
2219
}
2115
2220
2116
2221
void addTypeAliasRef (const TypeAliasDecl *TAD, DeclVisibilityKind Reason) {
2222
+ clang::comments::CommandWordsPairs Pairs;
2117
2223
CodeCompletionResultBuilder Builder (
2118
2224
Sink,
2119
2225
CodeCompletionResult::ResultKind::Declaration,
2120
2226
getSemanticContext (TAD, Reason), ExpectedTypes);
2121
2227
Builder.setAssociatedDecl (TAD);
2122
- setClangDeclKeywords (TAD, Builder);
2228
+ setClangDeclKeywords (TAD, Pairs, Builder);
2123
2229
addLeadingDot (Builder);
2124
2230
Builder.addTextChunk (TAD->getName ().str ());
2125
2231
if (TAD->hasUnderlyingType () && !TAD->getUnderlyingType ()->is <ErrorType>())
@@ -2131,11 +2237,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2131
2237
2132
2238
void addGenericTypeParamRef (const GenericTypeParamDecl *GP,
2133
2239
DeclVisibilityKind Reason) {
2240
+ clang::comments::CommandWordsPairs Pairs;
2134
2241
CodeCompletionResultBuilder Builder (
2135
2242
Sink,
2136
2243
CodeCompletionResult::ResultKind::Declaration,
2137
2244
getSemanticContext (GP, Reason), ExpectedTypes);
2138
- setClangDeclKeywords (GP, Builder);
2245
+ setClangDeclKeywords (GP, Pairs, Builder);
2139
2246
Builder.setAssociatedDecl (GP);
2140
2247
addLeadingDot (Builder);
2141
2248
Builder.addTextChunk (GP->getName ().str ());
@@ -2144,11 +2251,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2144
2251
2145
2252
void addAssociatedTypeRef (const AssociatedTypeDecl *AT,
2146
2253
DeclVisibilityKind Reason) {
2254
+ clang::comments::CommandWordsPairs Pairs;
2147
2255
CodeCompletionResultBuilder Builder (
2148
2256
Sink,
2149
2257
CodeCompletionResult::ResultKind::Declaration,
2150
2258
getSemanticContext (AT, Reason), ExpectedTypes);
2151
- setClangDeclKeywords (AT, Builder);
2259
+ setClangDeclKeywords (AT, Pairs, Builder);
2152
2260
Builder.setAssociatedDecl (AT);
2153
2261
addLeadingDot (Builder);
2154
2262
Builder.addTextChunk (AT->getName ().str ());
@@ -2161,14 +2269,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2161
2269
bool HasTypeContext) {
2162
2270
if (!EED->hasName ())
2163
2271
return ;
2164
-
2272
+ clang::comments::CommandWordsPairs Pairs;
2165
2273
CodeCompletionResultBuilder Builder (
2166
2274
Sink,
2167
2275
CodeCompletionResult::ResultKind::Declaration,
2168
2276
HasTypeContext ? SemanticContextKind::ExpressionSpecific
2169
2277
: getSemanticContext (EED, Reason), ExpectedTypes);
2170
2278
Builder.setAssociatedDecl (EED);
2171
- setClangDeclKeywords (EED, Builder);
2279
+ setClangDeclKeywords (EED, Pairs, Builder);
2172
2280
addLeadingDot (Builder);
2173
2281
Builder.addTextChunk (EED->getName ().str ());
2174
2282
if (EED->hasArgumentType ())
0 commit comments