Skip to content

Commit 65ef802

Browse files
committed
[CodeComplete] Add option to add calls with no defaults (or not)
Now that arguments are marked up with whether they have a default or not, clients may not need the extra call (that has no default arguments). Add an option to allow not adding this item. Resolves rdar://85526214.
1 parent 4187875 commit 65ef802

File tree

8 files changed

+90
-63
lines changed

8 files changed

+90
-63
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,9 @@ struct CodeCompletionResultSink {
962962
/// Whether to perform "call pettern heuristics".
963963
bool enableCallPatternHeuristics = false;
964964

965+
/// Whether to include an item without any default arguments.
966+
bool addCallWithNoDefaultArgs = true;
967+
965968
std::vector<CodeCompletionResult *> Results;
966969

967970
/// A single-element cache for module names stored in Allocator, keyed by a
@@ -1054,6 +1057,13 @@ class CodeCompletionContext {
10541057
return CurrentResults.enableCallPatternHeuristics;
10551058
}
10561059

1060+
void setAddCallWithNoDefaultArgs(bool flag) {
1061+
CurrentResults.addCallWithNoDefaultArgs = flag;
1062+
}
1063+
bool addCallWithNoDefaultArgs() const {
1064+
return CurrentResults.addCallWithNoDefaultArgs;
1065+
}
1066+
10571067
/// Allocate a string owned by the code completion context.
10581068
StringRef copyString(StringRef Str);
10591069

include/swift/IDE/CodeCompletionCache.h

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
#ifndef SWIFT_IDE_CODE_COMPLETIONCACHE_H
1414
#define SWIFT_IDE_CODE_COMPLETIONCACHE_H
1515

16-
#include "swift/IDE/CodeCompletion.h"
1716
#include "swift/Basic/ThreadSafeRefCounted.h"
17+
#include "swift/IDE/CodeCompletion.h"
18+
#include "llvm/ADT/Hashing.h"
1819
#include "llvm/ADT/IntrusiveRefCntPtr.h"
1920
#include "llvm/Support/Chrono.h"
2021
#include <system_error>
@@ -43,17 +44,19 @@ class CodeCompletionCache {
4344
bool ForTestableLookup;
4445
bool ForPrivateImportLookup;
4546
bool AddInitsInToplevel;
47+
bool AddCallWithNoDefaultArgs;
4648
bool Annotated;
4749

4850
friend bool operator==(const Key &LHS, const Key &RHS) {
4951
return LHS.ModuleFilename == RHS.ModuleFilename &&
50-
LHS.ModuleName == RHS.ModuleName &&
51-
LHS.AccessPath == RHS.AccessPath &&
52-
LHS.ResultsHaveLeadingDot == RHS.ResultsHaveLeadingDot &&
53-
LHS.ForTestableLookup == RHS.ForTestableLookup &&
54-
LHS.ForPrivateImportLookup == RHS.ForPrivateImportLookup &&
55-
LHS.AddInitsInToplevel == RHS.AddInitsInToplevel &&
56-
LHS.Annotated == RHS.Annotated;
52+
LHS.ModuleName == RHS.ModuleName &&
53+
LHS.AccessPath == RHS.AccessPath &&
54+
LHS.ResultsHaveLeadingDot == RHS.ResultsHaveLeadingDot &&
55+
LHS.ForTestableLookup == RHS.ForTestableLookup &&
56+
LHS.ForPrivateImportLookup == RHS.ForPrivateImportLookup &&
57+
LHS.AddInitsInToplevel == RHS.AddInitsInToplevel &&
58+
LHS.AddCallWithNoDefaultArgs == RHS.AddCallWithNoDefaultArgs &&
59+
LHS.Annotated == RHS.Annotated;
5760
}
5861
};
5962

@@ -110,23 +113,18 @@ template<>
110113
struct DenseMapInfo<swift::ide::CodeCompletionCache::Key> {
111114
using KeyTy = swift::ide::CodeCompletionCache::Key;
112115
static inline KeyTy getEmptyKey() {
113-
return KeyTy{"", "", {}, false, false, false, false, false};
116+
return KeyTy{"", "", {}, false, false, false, false, false, false};
114117
}
115118
static inline KeyTy getTombstoneKey() {
116-
return KeyTy{"", "", {}, true, false, false, false, false};
119+
return KeyTy{"", "", {}, true, false, false, false, false, false};
117120
}
118121
static unsigned getHashValue(const KeyTy &Val) {
119-
size_t H = 0;
120-
H ^= std::hash<std::string>()(Val.ModuleFilename);
121-
H ^= std::hash<std::string>()(Val.ModuleName);
122-
for (auto Piece : Val.AccessPath)
123-
H ^= std::hash<std::string>()(Piece);
124-
H ^= std::hash<bool>()(Val.ResultsHaveLeadingDot);
125-
H ^= std::hash<bool>()(Val.ForTestableLookup);
126-
H ^= std::hash<bool>()(Val.ForPrivateImportLookup);
127-
H ^= std::hash<bool>()(Val.AddInitsInToplevel);
128-
H ^= std::hash<bool>()(Val.Annotated);
129-
return static_cast<unsigned>(H);
122+
return llvm::hash_combine(
123+
Val.ModuleFilename, Val.ModuleName,
124+
llvm::hash_combine_range(Val.AccessPath.begin(), Val.AccessPath.end()),
125+
Val.ResultsHaveLeadingDot, Val.ForTestableLookup,
126+
Val.ForPrivateImportLookup, Val.AddInitsInToplevel,
127+
Val.AddCallWithNoDefaultArgs, Val.Annotated);
130128
}
131129
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
132130
return LHS == RHS;

lib/IDE/CodeCompletion.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,8 +2777,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
27772777
}
27782778
}
27792779

2780-
static bool hasInterestingDefaultValues(const AbstractFunctionDecl *func) {
2781-
if (!func) return false;
2780+
bool addItemWithoutDefaultArgs(const AbstractFunctionDecl *func) {
2781+
if (!func || !Sink.addCallWithNoDefaultArgs)
2782+
return false;
27822783
for (auto param : *func->getParameters()) {
27832784
if (hasInterestingDefaultValue(param))
27842785
return true;
@@ -3078,7 +3079,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
30783079
if (isImplicitlyCurriedInstanceMethod) {
30793080
addPattern({AFD->getImplicitSelfDecl()}, /*includeDefaultArgs=*/true);
30803081
} else {
3081-
if (hasInterestingDefaultValues(AFD))
3082+
if (addItemWithoutDefaultArgs(AFD))
30823083
addPattern(AFD->getParameters()->getArray(),
30833084
/*includeDefaultArgs=*/false);
30843085
addPattern(AFD->getParameters()->getArray(),
@@ -3282,7 +3283,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
32823283
if (trivialTrailingClosure)
32833284
addMethodImpl(/*includeDefaultArgs=*/false,
32843285
/*trivialTrailingClosure=*/true);
3285-
if (hasInterestingDefaultValues(FD))
3286+
if (addItemWithoutDefaultArgs(FD))
32863287
addMethodImpl(/*includeDefaultArgs=*/false);
32873288
addMethodImpl(/*includeDefaultArgs=*/true);
32883289
}
@@ -3372,8 +3373,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
33723373
}
33733374
};
33743375

3375-
if (ConstructorType && hasInterestingDefaultValues(CD))
3376-
addConstructorImpl(/*includeDefaultArgs*/ false);
3376+
if (ConstructorType && addItemWithoutDefaultArgs(CD))
3377+
addConstructorImpl(/*includeDefaultArgs=*/false);
33773378
addConstructorImpl();
33783379
}
33793380

@@ -6653,8 +6654,8 @@ static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
66536654
AccessLevel::Internal, TheModule,
66546655
SourceFile::ImportQueryKind::PrivateOnly),
66556656
CompletionContext.getAddInitsToTopLevel(),
6656-
CompletionContext.getAnnotateResult(),
6657-
};
6657+
CompletionContext.addCallWithNoDefaultArgs(),
6658+
CompletionContext.getAnnotateResult()};
66586659

66596660
using PairType = llvm::DenseSet<swift::ide::CodeCompletionCache::Key,
66606661
llvm::DenseMapInfo<CodeCompletionCache::Key>>::iterator;
@@ -7548,6 +7549,7 @@ void SimpleCachingCodeCompletionConsumer::handleResultsAndModules(
75487549
Sink.addInitsToTopLevel = context.getAddInitsToTopLevel();
75497550
Sink.enableCallPatternHeuristics = context.getCallPatternHeuristics();
75507551
Sink.includeObjectLiterals = context.includeObjectLiterals();
7552+
Sink.addCallWithNoDefaultArgs = context.addCallWithNoDefaultArgs();
75517553
lookupCodeCompletionResultsFromModule(
75527554
(*V)->Sink, R.TheModule, R.Key.AccessPath,
75537555
R.Key.ResultsHaveLeadingDot, SF);

lib/IDE/CodeCompletionCache.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ static void writeCachedModule(llvm::raw_ostream &out,
293293
OSSLE.write(K.ForTestableLookup);
294294
OSSLE.write(K.ForPrivateImportLookup);
295295
OSSLE.write(K.AddInitsInToplevel);
296+
OSSLE.write(K.AddCallWithNoDefaultArgs);
296297
OSSLE.write(K.Annotated);
297298
LE.write(static_cast<uint32_t>(OSS.tell())); // Size of debug info
298299
out.write(OSS.str().data(), OSS.str().size()); // Debug info blob
@@ -399,11 +400,12 @@ static std::string getName(StringRef cacheDirectory,
399400
llvm::sys::path::append(name, K.ModuleName);
400401
llvm::raw_svector_ostream OSS(name);
401402

402-
// name[-dot][-testable][-inits]
403+
// name[-with-enabled-options]
403404
OSS << (K.ResultsHaveLeadingDot ? "-dot" : "")
404405
<< (K.ForTestableLookup ? "-testable" : "")
405406
<< (K.ForPrivateImportLookup ? "-private" : "")
406407
<< (K.AddInitsInToplevel ? "-inits" : "")
408+
<< (K.AddCallWithNoDefaultArgs ? "-nodefaults" : "")
407409
<< (K.Annotated ? "-annotated" : "");
408410

409411
// name[-access-path-components]
@@ -469,8 +471,9 @@ OnDiskCodeCompletionCache::getFromFile(StringRef filename) {
469471
return None;
470472

471473
// Make up a key for readCachedModule.
472-
CodeCompletionCache::Key K{filename.str(), "<module-name>", {}, false,
473-
false, false, false, false};
474+
CodeCompletionCache::Key K{filename.str(), "<module-name>", {},
475+
false, false, false,
476+
false, false, false};
474477

475478
// Read the cached results.
476479
auto V = CodeCompletionCache::createValue();

test/IDE/complete_default_arguments.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARGS_1 | %FileCheck %s -check-prefix=DEFAULT_ARGS_1
55
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARGS_2 | %FileCheck %s -check-prefix=DEFAULT_ARGS_2
6+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-complete-add-call-with-no-default-args=false -code-completion-token=DEFAULT_ARGS_2 | %FileCheck %s --check-prefix=ONLY_DEFAULTS
67
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARGS_3 | %FileCheck %s -check-prefix=DEFAULT_ARGS_3
78
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARGS_4 | %FileCheck %s -check-prefix=DEFAULT_ARGS_4
89
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEFAULT_ARGS_5 | %FileCheck %s -check-prefix=DEFAULT_ARGS_5
@@ -81,6 +82,10 @@ func testDefaultArgs2() {
8182
// DEFAULT_ARGS_2-DAG: Decl[FreeFunction]/CurrModule/Flair[ArgLabels]: ({#(a): Int#}, {#b: Int#})[#Void#]{{; name=.+$}}
8283
// DEFAULT_ARGS_2: End completions
8384

85+
// ONLY_DEFAULTS: Begin completions
86+
// ONLY_DEFAULTS-NEXT: Decl[FreeFunction]/CurrModule/Flair[ArgLabels]: ({#(a): Int#}, {#b: Int#})[#Void#]{{; name=.+$}}
87+
// ONLY_DEFAULTS: End completions
88+
8489
func testDefaultArgs3() {
8590
freeFuncWithDefaultArgs3#^DEFAULT_ARGS_3^#
8691
}

tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct Options {
4545
bool fuzzyMatching = true;
4646
bool annotatedDescription = false;
4747
bool includeObjectLiterals = true;
48+
bool addCallWithNoDefaultArgs = true;
4849
unsigned minFuzzyLength = 2;
4950
unsigned showTopNonLiteralResults = 3;
5051

tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static void swiftCodeCompleteImpl(
107107
CompletionContext.setIncludeObjectLiterals(opts.includeObjectLiterals);
108108
CompletionContext.setAddInitsToTopLevel(opts.addInitsToTopLevel);
109109
CompletionContext.setCallPatternHeuristics(opts.callPatternHeuristics);
110+
CompletionContext.setAddCallWithNoDefaultArgs(opts.addCallWithNoDefaultArgs);
110111

111112
Lang.performWithParamsToCompletionLikeOperation(
112113
UnresolvedInputFile, Offset, Args, FileSystem, CancellationToken,

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,12 @@ DebugClientDiscriminator("debug-client-discriminator",
486486
llvm::cl::desc("A discriminator to prefer in lookups"),
487487
llvm::cl::cat(Category));
488488

489+
static llvm::cl::opt<bool> CodeCompletionAddCallWithNoDefaultArgs(
490+
"code-complete-add-call-with-no-default-args",
491+
llvm::cl::desc("Whether to include a function completion that contains no "
492+
"default arguments"),
493+
llvm::cl::cat(Category), llvm::cl::init(true));
494+
489495
// '-conforming-methods' options.
490496

491497
static llvm::cl::list<std::string>
@@ -1137,17 +1143,16 @@ static int printCodeCompletionResults(
11371143
});
11381144
}
11391145

1140-
static int doCodeCompletion(const CompilerInvocation &InitInvok,
1141-
StringRef SourceFilename,
1142-
StringRef SecondSourceFileName,
1143-
StringRef CodeCompletionToken,
1144-
bool CodeCompletionDiagnostics,
1145-
bool CodeCompletionKeywords,
1146-
bool CodeCompletionComments,
1147-
bool CodeCompletionAnnotateResults,
1148-
bool CodeCompletionAddInitsToTopLevel,
1149-
bool CodeCompletionCallPatternHeuristics,
1150-
bool CodeCompletionSourceText) {
1146+
static int
1147+
doCodeCompletion(const CompilerInvocation &InitInvok, StringRef SourceFilename,
1148+
StringRef SecondSourceFileName, StringRef CodeCompletionToken,
1149+
bool CodeCompletionDiagnostics, bool CodeCompletionKeywords,
1150+
bool CodeCompletionComments,
1151+
bool CodeCompletionAnnotateResults,
1152+
bool CodeCompletionAddInitsToTopLevel,
1153+
bool CodeCompletionCallPatternHeuristics,
1154+
bool CodeCompletionAddCallWithNoDefaultArgs,
1155+
bool CodeCompletionSourceText) {
11511156
std::unique_ptr<ide::OnDiskCodeCompletionCache> OnDiskCache;
11521157
if (!options::CompletionCachePath.empty()) {
11531158
OnDiskCache = std::make_unique<ide::OnDiskCodeCompletionCache>(
@@ -1158,6 +1163,8 @@ static int doCodeCompletion(const CompilerInvocation &InitInvok,
11581163
CompletionContext.setAnnotateResult(CodeCompletionAnnotateResults);
11591164
CompletionContext.setAddInitsToTopLevel(CodeCompletionAddInitsToTopLevel);
11601165
CompletionContext.setCallPatternHeuristics(CodeCompletionCallPatternHeuristics);
1166+
CompletionContext.setAddCallWithNoDefaultArgs(
1167+
CodeCompletionAddCallWithNoDefaultArgs);
11611168

11621169
return performWithCompletionLikeOperationParams(
11631170
InitInvok, SourceFilename, SecondSourceFileName, CodeCompletionToken,
@@ -1359,6 +1366,7 @@ static int doBatchCodeCompletion(const CompilerInvocation &InitInvok,
13591366
bool CodeCompletionAnnotateResults,
13601367
bool CodeCompletionAddInitsToTopLevel,
13611368
bool CodeCompletionCallPatternHeuristics,
1369+
bool CodeCompletionAddCallWithNoDefaultArgs,
13621370
bool CodeCompletionSourceText) {
13631371
auto FileBufOrErr = llvm::MemoryBuffer::getFile(SourceFilename);
13641372
if (!FileBufOrErr) {
@@ -1488,6 +1496,8 @@ static int doBatchCodeCompletion(const CompilerInvocation &InitInvok,
14881496
CompletionContext.setAddInitsToTopLevel(CodeCompletionAddInitsToTopLevel);
14891497
CompletionContext.setCallPatternHeuristics(
14901498
CodeCompletionCallPatternHeuristics);
1499+
CompletionContext.setAddCallWithNoDefaultArgs(
1500+
CodeCompletionAddCallWithNoDefaultArgs);
14911501

14921502
PrintingDiagnosticConsumer PrintDiags;
14931503
auto completionStart = std::chrono::high_resolution_clock::now();
@@ -4415,33 +4425,30 @@ int main(int argc, char *argv[]) {
44154425
<< "'-skip-filecheck'\n";
44164426
return 1;
44174427
}
4418-
ExitCode = doBatchCodeCompletion(InitInvok,
4419-
options::SourceFilename,
4420-
options::CodeCompletionDiagnostics,
4421-
options::CodeCompletionKeywords,
4422-
options::CodeCompletionComments,
4423-
options::CodeCompletionAnnotateResults,
4424-
options::CodeCompleteInitsInPostfixExpr,
4425-
options::CodeCompleteCallPatternHeuristics,
4426-
options::CodeCompletionSourceText);
4428+
ExitCode = doBatchCodeCompletion(
4429+
InitInvok, options::SourceFilename, options::CodeCompletionDiagnostics,
4430+
options::CodeCompletionKeywords, options::CodeCompletionComments,
4431+
options::CodeCompletionAnnotateResults,
4432+
options::CodeCompleteInitsInPostfixExpr,
4433+
options::CodeCompleteCallPatternHeuristics,
4434+
options::CodeCompletionAddCallWithNoDefaultArgs,
4435+
options::CodeCompletionSourceText);
44274436
break;
44284437

44294438
case ActionType::CodeCompletion:
44304439
if (options::CodeCompletionToken.empty()) {
44314440
llvm::errs() << "code completion token name required\n";
44324441
return 1;
44334442
}
4434-
ExitCode = doCodeCompletion(InitInvok,
4435-
options::SourceFilename,
4436-
options::SecondSourceFilename,
4437-
options::CodeCompletionToken,
4438-
options::CodeCompletionDiagnostics,
4439-
options::CodeCompletionKeywords,
4440-
options::CodeCompletionComments,
4441-
options::CodeCompletionAnnotateResults,
4442-
options::CodeCompleteInitsInPostfixExpr,
4443-
options::CodeCompleteCallPatternHeuristics,
4444-
options::CodeCompletionSourceText);
4443+
ExitCode = doCodeCompletion(
4444+
InitInvok, options::SourceFilename, options::SecondSourceFilename,
4445+
options::CodeCompletionToken, options::CodeCompletionDiagnostics,
4446+
options::CodeCompletionKeywords, options::CodeCompletionComments,
4447+
options::CodeCompletionAnnotateResults,
4448+
options::CodeCompleteInitsInPostfixExpr,
4449+
options::CodeCompleteCallPatternHeuristics,
4450+
options::CodeCompletionAddCallWithNoDefaultArgs,
4451+
options::CodeCompletionSourceText);
44454452
break;
44464453

44474454
case ActionType::REPLCodeCompletion:

0 commit comments

Comments
 (0)