Skip to content

Commit 3fe6782

Browse files
authored
Merge pull request swiftlang#41400 from rintaro/completion-fitername-precompute
[CodeCompletion] Precompute "filter name"
2 parents 035fa37 + 3c33deb commit 3fe6782

File tree

12 files changed

+325
-232
lines changed

12 files changed

+325
-232
lines changed

include/swift/Basic/StringExtras.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,16 @@ namespace swift {
5252
/// Determine the part of speech for the given word.
5353
PartOfSpeech getPartOfSpeech(StringRef word);
5454

55+
/// Copy \p string to \p Allocator and return it as a null terminated C
56+
/// string.
57+
const char *copyCString(StringRef string, llvm::BumpPtrAllocator &Allocator);
58+
5559
/// Scratch space used for returning a set of StringRefs.
5660
class StringScratchSpace {
5761
llvm::BumpPtrAllocator Allocator;
5862

5963
public:
60-
StringRef copyString(StringRef string);
64+
StringRef copyString(StringRef string) { return string.copy(Allocator); }
6165

6266
llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
6367
};
@@ -465,6 +469,52 @@ bool omitNeedlessWords(StringRef &baseName,
465469
/// If the name has a completion-handler suffix, strip off that suffix.
466470
Optional<StringRef> stripWithCompletionHandlerSuffix(StringRef name);
467471

472+
/// Represents a string that can be efficiently retrieved either as a StringRef
473+
/// or as a null-terminated C string.
474+
class NullTerminatedStringRef {
475+
StringRef Ref;
476+
477+
public:
478+
/// Create a \c NullTerminatedStringRef from a null-terminated C string with
479+
/// size \p Size (excluding the null character).
480+
NullTerminatedStringRef(const char *Data, size_t Size) : Ref(Data, Size) {
481+
assert(Data != nullptr && Data[Size] == '\0' &&
482+
"Data should be null-terminated");
483+
}
484+
485+
/// Create an empty null-terminated string. \c data() is not a \c nullptr.
486+
constexpr NullTerminatedStringRef() : Ref("") {}
487+
488+
/// Create an null terminated string with a C string.
489+
constexpr NullTerminatedStringRef(const char *Data) : Ref(Data) {}
490+
491+
/// Create a null-terminated string, copying \p Str into \p A .
492+
template <typename Allocator>
493+
NullTerminatedStringRef(StringRef Str, Allocator &A) : Ref("") {
494+
if (Str.empty())
495+
return;
496+
497+
size_t size = Str.size();
498+
char *memory = A.template Allocate<char>(size + 1);
499+
memcpy(memory, Str.data(), size);
500+
memory[size] = '\0';
501+
Ref = {memory, size};
502+
}
503+
504+
/// Returns the string as a `StringRef`. The `StringRef` does not include the
505+
/// null character.
506+
operator StringRef() const { return Ref; }
507+
508+
/// Returns the string as a null-terminated C string.
509+
const char *data() const { return Ref.data(); }
510+
511+
/// The size of the string, excluding the null character.
512+
size_t size() const { return Ref.size(); }
513+
514+
bool empty() const { return Ref.empty(); }
515+
int compare(NullTerminatedStringRef RHS) const { return Ref.compare(RHS); }
516+
};
517+
468518
} // end namespace swift
469519

470520
#endif // SWIFT_BASIC_STRINGEXTRAS_H

include/swift/IDE/CodeCompletion.h

Lines changed: 65 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/Basic/Debug.h"
1919
#include "swift/Basic/LLVM.h"
2020
#include "swift/Basic/OptionSet.h"
21+
#include "swift/Basic/StringExtras.h"
2122
#include "swift/Frontend/Frontend.h"
2223
#include "llvm/ADT/ArrayRef.h"
2324
#include "llvm/ADT/StringMap.h"
@@ -64,12 +65,6 @@ std::string removeCodeCompletionTokens(StringRef Input,
6465
StringRef TokenName,
6566
unsigned *CompletionOffset);
6667

67-
StringRef copyString(llvm::BumpPtrAllocator &Allocator,
68-
StringRef Str);
69-
70-
const char *copyCString(llvm::BumpPtrAllocator &Allocator,
71-
StringRef Str);
72-
7368
template <typename T>
7469
ArrayRef<T> copyArray(llvm::BumpPtrAllocator &Allocator,
7570
ArrayRef<T> Arr) {
@@ -723,9 +718,9 @@ class ContextFreeCodeCompletionResult {
723718

724719
bool IsSystem : 1;
725720
CodeCompletionString *CompletionString;
726-
StringRef ModuleName;
727-
StringRef BriefDocComment;
728-
ArrayRef<StringRef> AssociatedUSRs;
721+
NullTerminatedStringRef ModuleName;
722+
NullTerminatedStringRef BriefDocComment;
723+
ArrayRef<NullTerminatedStringRef> AssociatedUSRs;
729724
CodeCompletionResultType ResultType;
730725

731726
ContextFreeNotRecommendedReason NotRecommended : 3;
@@ -734,7 +729,8 @@ class ContextFreeCodeCompletionResult {
734729
CodeCompletionDiagnosticSeverity DiagnosticSeverity : 3;
735730
static_assert(int(CodeCompletionDiagnosticSeverity::MAX_VALUE) < 1 << 3, "");
736731

737-
StringRef DiagnosticMessage;
732+
NullTerminatedStringRef DiagnosticMessage;
733+
NullTerminatedStringRef FilterName;
738734

739735
public:
740736
/// Memberwise initializer. \p AssociatedKInd is opaque and will be
@@ -748,18 +744,21 @@ class ContextFreeCodeCompletionResult {
748744
ContextFreeCodeCompletionResult(
749745
CodeCompletionResultKind Kind, uint8_t AssociatedKind,
750746
CodeCompletionOperatorKind KnownOperatorKind, bool IsSystem,
751-
CodeCompletionString *CompletionString, StringRef ModuleName,
752-
StringRef BriefDocComment, ArrayRef<StringRef> AssociatedUSRs,
747+
CodeCompletionString *CompletionString,
748+
NullTerminatedStringRef ModuleName,
749+
NullTerminatedStringRef BriefDocComment,
750+
ArrayRef<NullTerminatedStringRef> AssociatedUSRs,
753751
CodeCompletionResultType ResultType,
754752
ContextFreeNotRecommendedReason NotRecommended,
755753
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
756-
StringRef DiagnosticMessage)
754+
NullTerminatedStringRef DiagnosticMessage,
755+
NullTerminatedStringRef FilterName)
757756
: Kind(Kind), KnownOperatorKind(KnownOperatorKind), IsSystem(IsSystem),
758757
CompletionString(CompletionString), ModuleName(ModuleName),
759758
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
760759
ResultType(ResultType), NotRecommended(NotRecommended),
761760
DiagnosticSeverity(DiagnosticSeverity),
762-
DiagnosticMessage(DiagnosticMessage) {
761+
DiagnosticMessage(DiagnosticMessage), FilterName(FilterName) {
763762
this->AssociatedKind.Opaque = AssociatedKind;
764763
assert((NotRecommended == ContextFreeNotRecommendedReason::None) ==
765764
(DiagnosticSeverity == CodeCompletionDiagnosticSeverity::None) &&
@@ -777,78 +776,58 @@ class ContextFreeCodeCompletionResult {
777776
"isOperator implies operator kind != None");
778777
}
779778

780-
/// Constructs a \c Pattern, \c Keyword or \c BuiltinOperator result.
779+
/// Constructs a \c Pattern or \c BuiltinOperator result.
781780
///
782781
/// \note The caller must ensure that the \p CompletionString and \c
783782
/// StringRefs outlive this result, typically by storing them in the same
784783
/// \c CodeCompletionResultSink as the result itself.
785-
ContextFreeCodeCompletionResult(
786-
CodeCompletionResultKind Kind, CodeCompletionString *CompletionString,
787-
CodeCompletionOperatorKind KnownOperatorKind, StringRef BriefDocComment,
784+
static ContextFreeCodeCompletionResult *createPatternOrBuiltInOperatorResult(
785+
llvm::BumpPtrAllocator &Allocator, CodeCompletionResultKind Kind,
786+
CodeCompletionString *CompletionString,
787+
CodeCompletionOperatorKind KnownOperatorKind,
788+
NullTerminatedStringRef BriefDocComment,
788789
CodeCompletionResultType ResultType,
789790
ContextFreeNotRecommendedReason NotRecommended,
790791
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
791-
StringRef DiagnosticMessage)
792-
: ContextFreeCodeCompletionResult(
793-
Kind, /*AssociatedKind=*/0, KnownOperatorKind,
794-
/*IsSystem=*/false, CompletionString, /*ModuleName=*/"",
795-
BriefDocComment, /*AssociatedUSRs=*/{}, ResultType, NotRecommended,
796-
DiagnosticSeverity, DiagnosticMessage) {}
792+
NullTerminatedStringRef DiagnosticMessage);
797793

798794
/// Constructs a \c Keyword result.
799795
///
800796
/// \note The caller must ensure that the \p CompletionString and
801-
/// \p BriefDocComment outlive this result, typically by storing them in the
802-
/// same \c CodeCompletionResultSink as the result itself.
803-
ContextFreeCodeCompletionResult(CodeCompletionKeywordKind Kind,
804-
CodeCompletionString *CompletionString,
805-
StringRef BriefDocComment,
806-
CodeCompletionResultType ResultType)
807-
: ContextFreeCodeCompletionResult(
808-
CodeCompletionResultKind::Keyword, static_cast<uint8_t>(Kind),
809-
CodeCompletionOperatorKind::None, /*IsSystem=*/false,
810-
CompletionString, /*ModuleName=*/"", BriefDocComment,
811-
/*AssociatedUSRs=*/{}, ResultType,
812-
ContextFreeNotRecommendedReason::None,
813-
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"") {}
797+
/// \p BriefDocComment outlive this result, typically by storing them in
798+
/// the same \c CodeCompletionResultSink as the result itself.
799+
static ContextFreeCodeCompletionResult *
800+
createKeywordResult(llvm::BumpPtrAllocator &Allocator,
801+
CodeCompletionKeywordKind Kind,
802+
CodeCompletionString *CompletionString,
803+
NullTerminatedStringRef BriefDocComment,
804+
CodeCompletionResultType ResultType);
814805

815806
/// Constructs a \c Literal result.
816807
///
817808
/// \note The caller must ensure that the \p CompletionString outlives this
818809
/// result, typically by storing them in the same \c CodeCompletionResultSink
819810
/// as the result itself.
820-
ContextFreeCodeCompletionResult(CodeCompletionLiteralKind LiteralKind,
821-
CodeCompletionString *CompletionString,
822-
CodeCompletionResultType ResultType)
823-
: ContextFreeCodeCompletionResult(
824-
CodeCompletionResultKind::Literal,
825-
static_cast<uint8_t>(LiteralKind), CodeCompletionOperatorKind::None,
826-
/*IsSystem=*/false, CompletionString, /*ModuleName=*/"",
827-
/*BriefDocComment=*/"",
828-
/*AssociatedUSRs=*/{}, ResultType,
829-
ContextFreeNotRecommendedReason::None,
830-
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"") {}
811+
static ContextFreeCodeCompletionResult *
812+
createLiteralResult(llvm::BumpPtrAllocator &Allocator,
813+
CodeCompletionLiteralKind LiteralKind,
814+
CodeCompletionString *CompletionString,
815+
CodeCompletionResultType ResultType);
831816

832817
/// Constructs a \c Declaration result.
833818
///
834819
/// \note The caller must ensure that the \p CompletionString and all
835820
/// \c StringRefs outlive this result, typically by storing them in the same
836821
/// \c CodeCompletionResultSink as the result itself.
837-
ContextFreeCodeCompletionResult(
838-
CodeCompletionString *CompletionString, const Decl *AssociatedDecl,
839-
StringRef ModuleName, StringRef BriefDocComment,
840-
ArrayRef<StringRef> AssociatedUSRs, CodeCompletionResultType ResultType,
822+
static ContextFreeCodeCompletionResult *createDeclResult(
823+
llvm::BumpPtrAllocator &Allocator, CodeCompletionString *CompletionString,
824+
const Decl *AssociatedDecl, NullTerminatedStringRef ModuleName,
825+
NullTerminatedStringRef BriefDocComment,
826+
ArrayRef<NullTerminatedStringRef> AssociatedUSRs,
827+
CodeCompletionResultType ResultType,
841828
ContextFreeNotRecommendedReason NotRecommended,
842829
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
843-
StringRef DiagnosticMessage)
844-
: ContextFreeCodeCompletionResult(
845-
CodeCompletionResultKind::Declaration,
846-
static_cast<uint8_t>(getCodeCompletionDeclKind(AssociatedDecl)),
847-
CodeCompletionOperatorKind::None, getDeclIsSystem(AssociatedDecl),
848-
CompletionString, ModuleName, BriefDocComment, AssociatedUSRs,
849-
ResultType, NotRecommended, DiagnosticSeverity, DiagnosticMessage) {
850-
assert(AssociatedDecl && "should have a decl");
851-
}
830+
NullTerminatedStringRef DiagnosticMessage);
852831

853832
CodeCompletionResultKind getKind() const { return Kind; }
854833

@@ -878,11 +857,13 @@ class ContextFreeCodeCompletionResult {
878857

879858
CodeCompletionString *getCompletionString() const { return CompletionString; }
880859

881-
StringRef getModuleName() const { return ModuleName; }
860+
NullTerminatedStringRef getModuleName() const { return ModuleName; }
882861

883-
StringRef getBriefDocComment() const { return BriefDocComment; }
862+
NullTerminatedStringRef getBriefDocComment() const { return BriefDocComment; }
884863

885-
ArrayRef<StringRef> getAssociatedUSRs() const { return AssociatedUSRs; }
864+
ArrayRef<NullTerminatedStringRef> getAssociatedUSRs() const {
865+
return AssociatedUSRs;
866+
}
886867

887868
const CodeCompletionResultType &getResultType() const { return ResultType; }
888869

@@ -893,7 +874,11 @@ class ContextFreeCodeCompletionResult {
893874
CodeCompletionDiagnosticSeverity getDiagnosticSeverity() const {
894875
return DiagnosticSeverity;
895876
}
896-
StringRef getDiagnosticMessage() const { return DiagnosticMessage; };
877+
NullTerminatedStringRef getDiagnosticMessage() const {
878+
return DiagnosticMessage;
879+
}
880+
881+
NullTerminatedStringRef getFilterName() const { return FilterName; }
897882

898883
bool isOperator() const {
899884
if (getKind() == CodeCompletionResultKind::Declaration) {
@@ -935,7 +920,7 @@ class CodeCompletionResult {
935920
CodeCompletionDiagnosticSeverity DiagnosticSeverity : 3;
936921
static_assert(int(CodeCompletionDiagnosticSeverity::MAX_VALUE) < 1 << 3, "");
937922

938-
StringRef DiagnosticMessage;
923+
NullTerminatedStringRef DiagnosticMessage;
939924

940925
/// The number of bytes to the left of the code completion point that
941926
/// should be erased first if this completion string is inserted in the
@@ -959,7 +944,7 @@ class CodeCompletionResult {
959944
CodeCompletionResultTypeRelation TypeDistance,
960945
ContextualNotRecommendedReason NotRecommended,
961946
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
962-
StringRef DiagnosticMessage)
947+
NullTerminatedStringRef DiagnosticMessage)
963948
: ContextFree(ContextFree), SemanticContext(SemanticContext),
964949
Flair(Flair.toRaw()), NotRecommended(NotRecommended),
965950
DiagnosticSeverity(DiagnosticSeverity),
@@ -981,7 +966,7 @@ class CodeCompletionResult {
981966
const DeclContext *DC,
982967
ContextualNotRecommendedReason NotRecommended,
983968
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
984-
StringRef DiagnosticMessage);
969+
NullTerminatedStringRef DiagnosticMessage);
985970

986971
const ContextFreeCodeCompletionResult &getContextFreeResult() const {
987972
return ContextFree;
@@ -1090,15 +1075,15 @@ class CodeCompletionResult {
10901075
return getContextFreeResult().getCompletionString();
10911076
}
10921077

1093-
StringRef getModuleName() const {
1078+
NullTerminatedStringRef getModuleName() const {
10941079
return getContextFreeResult().getModuleName();
10951080
}
10961081

1097-
StringRef getBriefDocComment() const {
1082+
NullTerminatedStringRef getBriefDocComment() const {
10981083
return getContextFreeResult().getBriefDocComment();
10991084
}
11001085

1101-
ArrayRef<StringRef> getAssociatedUSRs() const {
1086+
ArrayRef<NullTerminatedStringRef> getAssociatedUSRs() const {
11021087
return getContextFreeResult().getAssociatedUSRs();
11031088
}
11041089

@@ -1110,7 +1095,9 @@ class CodeCompletionResult {
11101095

11111096
/// Get the contextual diagnostic message. This disregards context-free
11121097
/// diagnostics.
1113-
StringRef getContextualDiagnosticMessage() const { return DiagnosticMessage; }
1098+
NullTerminatedStringRef getContextualDiagnosticMessage() const {
1099+
return DiagnosticMessage;
1100+
}
11141101

11151102
/// Return the contextual diagnostic severity if there was a contextual
11161103
/// diagnostic. If there is no contextual diagnostic, return the context-free
@@ -1126,14 +1113,18 @@ class CodeCompletionResult {
11261113
/// Return the contextual diagnostic message if there was a contextual
11271114
/// diagnostic. If there is no contextual diagnostic, return the context-free
11281115
/// diagnostic message.
1129-
StringRef getDiagnosticMessage() const {
1116+
NullTerminatedStringRef getDiagnosticMessage() const {
11301117
if (NotRecommended != ContextualNotRecommendedReason::None) {
11311118
return DiagnosticMessage;
11321119
} else {
11331120
return getContextFreeResult().getDiagnosticMessage();
11341121
}
11351122
}
11361123

1124+
NullTerminatedStringRef getFilterName() const {
1125+
return getContextFreeResult().getFilterName();
1126+
}
1127+
11371128
/// Print a debug representation of the code completion result to \p OS.
11381129
void printPrefix(raw_ostream &OS) const;
11391130
SWIFT_DEBUG_DUMP;
@@ -1169,7 +1160,7 @@ struct CodeCompletionResultSink {
11691160

11701161
/// A single-element cache for module names stored in Allocator, keyed by a
11711162
/// clang::Module * or swift::ModuleDecl *.
1172-
std::pair<void *, StringRef> LastModule;
1163+
std::pair<void *, NullTerminatedStringRef> LastModule;
11731164

11741165
CodeCompletionResultSink()
11751166
: Allocator(std::make_shared<llvm::BumpPtrAllocator>()) {}

include/swift/IDE/CodeCompletionResultPrinter.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@
1313
#ifndef SWIFT_IDE_CODECOMPLETIONRESULTPRINTER_H
1414
#define SWIFT_IDE_CODECOMPLETIONRESULTPRINTER_H
1515

16+
#include "llvm/ADT/StringRef.h"
1617
#include "llvm/Support/raw_ostream.h"
18+
#include "llvm/Support/Allocator.h"
1719

1820
namespace swift {
21+
22+
class NullTerminatedStringRef;
23+
1924
namespace ide {
2025

2126
class CodeCompletionResult;
27+
class CodeCompletionString;
2228

2329
void printCodeCompletionResultDescription(const CodeCompletionResult &Result,
2430
llvm::raw_ostream &OS,
@@ -37,8 +43,11 @@ void printCodeCompletionResultTypeNameAnnotated(
3743
void printCodeCompletionResultSourceText(
3844
const CodeCompletionResult &Result, llvm::raw_ostream &OS);
3945

40-
void printCodeCompletionResultFilterName(
41-
const CodeCompletionResult &Result, llvm::raw_ostream &OS);
46+
/// Print 'FilterName' from \p str into memory managed by \p Allocator and
47+
/// return it as \c NullTerminatedStringRef .
48+
NullTerminatedStringRef
49+
getCodeCompletionResultFilterName(const CodeCompletionString *Str,
50+
llvm::BumpPtrAllocator &Allocator);
4251

4352
} // namespace ide
4453
} // namespace swift

0 commit comments

Comments
 (0)