Skip to content

Commit 415e7ca

Browse files
committed
[CodeComplete] Show global completions from modules that are imported as @_spi
If a module is imported as `@_spi`, we didn’t receive any global completions from it. rdar://99027179
1 parent 36893aa commit 415e7ca

File tree

4 files changed

+70
-8
lines changed

4 files changed

+70
-8
lines changed

include/swift/IDE/CodeCompletionCache.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class CodeCompletionCache {
4545
bool ResultsHaveLeadingDot;
4646
bool ForTestableLookup;
4747
bool ForPrivateImportLookup;
48+
bool ForSPILookup;
4849
bool AddInitsInToplevel;
4950
bool AddCallWithNoDefaultArgs;
5051
bool Annotated;
@@ -56,6 +57,7 @@ class CodeCompletionCache {
5657
LHS.ResultsHaveLeadingDot == RHS.ResultsHaveLeadingDot &&
5758
LHS.ForTestableLookup == RHS.ForTestableLookup &&
5859
LHS.ForPrivateImportLookup == RHS.ForPrivateImportLookup &&
60+
LHS.ForSPILookup == RHS.ForSPILookup &&
5961
LHS.AddInitsInToplevel == RHS.AddInitsInToplevel &&
6062
LHS.AddCallWithNoDefaultArgs == RHS.AddCallWithNoDefaultArgs &&
6163
LHS.Annotated == RHS.Annotated;
@@ -125,10 +127,10 @@ template<>
125127
struct DenseMapInfo<swift::ide::CodeCompletionCache::Key> {
126128
using KeyTy = swift::ide::CodeCompletionCache::Key;
127129
static inline KeyTy getEmptyKey() {
128-
return KeyTy{"", "", {}, false, false, false, false, false, false};
130+
return KeyTy{"", "", {}, false, false, false, false, false, false, false};
129131
}
130132
static inline KeyTy getTombstoneKey() {
131-
return KeyTy{"", "", {}, true, false, false, false, false, false};
133+
return KeyTy{"", "", {}, true, false, false, false, false, false, false};
132134
}
133135
static unsigned getHashValue(const KeyTy &Val) {
134136
return llvm::hash_combine(

lib/IDE/CodeCompletion.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,11 @@ void swift::ide::deliverCompletionResults(
13011301
// ModuleFilename can be empty if something strange happened during
13021302
// module loading, for example, the module file is corrupted.
13031303
if (!ModuleFilename.empty()) {
1304+
bool ForSPILookup = llvm::any_of(
1305+
SF.getImports(), [&](AttributedImport<ImportedModule> desc) {
1306+
return desc.module.importedModule == TheModule &&
1307+
desc.options.contains(ImportFlags::SPIAccessControl);
1308+
});
13041309
CodeCompletionCache::Key K{
13051310
ModuleFilename.str(),
13061311
std::string(TheModule->getName()),
@@ -1312,6 +1317,7 @@ void swift::ide::deliverCompletionResults(
13121317
SF.hasTestableOrPrivateImport(
13131318
AccessLevel::Internal, TheModule,
13141319
SourceFile::ImportQueryKind::PrivateOnly),
1320+
ForSPILookup,
13151321
CompletionContext.getAddInitsToTopLevel(),
13161322
CompletionContext.addCallWithNoDefaultArgs(),
13171323
CompletionContext.getAnnotateResult()};
@@ -1351,9 +1357,12 @@ void swift::ide::deliverCompletionResults(
13511357
// Add results for all imported modules.
13521358
SmallVector<ImportedModule, 4> Imports;
13531359
SF.getImportedModules(
1354-
Imports, {ModuleDecl::ImportFilterKind::Exported,
1355-
ModuleDecl::ImportFilterKind::Default,
1356-
ModuleDecl::ImportFilterKind::ImplementationOnly});
1360+
Imports, {
1361+
ModuleDecl::ImportFilterKind::Exported,
1362+
ModuleDecl::ImportFilterKind::Default,
1363+
ModuleDecl::ImportFilterKind::ImplementationOnly,
1364+
ModuleDecl::ImportFilterKind::SPIAccessControl,
1365+
});
13571366

13581367
for (auto Imported : Imports) {
13591368
for (auto Import : namelookup::getAllImports(Imported.importedModule))

lib/IDE/CodeCompletionCache.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ static std::string getName(StringRef cacheDirectory,
481481
OSS << (K.ResultsHaveLeadingDot ? "-dot" : "")
482482
<< (K.ForTestableLookup ? "-testable" : "")
483483
<< (K.ForPrivateImportLookup ? "-private" : "")
484+
<< (K.ForSPILookup ? "-spi" : "")
484485
<< (K.AddInitsInToplevel ? "-inits" : "")
485486
<< (K.AddCallWithNoDefaultArgs ? "-nodefaults" : "")
486487
<< (K.Annotated ? "-annotated" : "");
@@ -548,9 +549,9 @@ OnDiskCodeCompletionCache::getFromFile(StringRef filename) {
548549
return None;
549550

550551
// Make up a key for readCachedModule.
551-
CodeCompletionCache::Key K{filename.str(), "<module-name>", {},
552-
false, false, false,
553-
false, false, false};
552+
CodeCompletionCache::Key K{
553+
filename.str(), "<module-name>", {}, false, false,
554+
false, false, false, false, false};
554555

555556
// Read the cached results.
556557
auto V = CodeCompletionCache::createValue();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %empty-directory(%t/split)
2+
// RUN: %empty-directory(%t/build)
3+
// RUN: %{python} %utils/split_file.py -o %t/split %s
4+
5+
// RUN: %target-swift-frontend -emit-module -o %t/build %t/split/pck.swift
6+
7+
// First SPI completion then completion in file without SPI import
8+
// RUN: %empty-directory(%t/cc-cache)
9+
// RUN: %target-swift-ide-test -code-completion -completion-cache-path %t/cc-cache -source-filename %t/split/with-spi-import.swift -I %t/build -code-completion-token=COMPLETE | %FileCheck %s --check-prefix=WITH_SPI
10+
// RUN: %target-swift-ide-test -code-completion -completion-cache-path %t/cc-cache -source-filename %t/split/with-normal-import.swift -I %t/build -code-completion-token=COMPLETE | %FileCheck %s --check-prefix=WITHOUT_SPI
11+
12+
// First completion in file without SPI import, then with SPI import
13+
// RUN: %empty-directory(%t/cc-cache)
14+
// RUN: %target-swift-ide-test -code-completion -completion-cache-path %t/cc-cache -source-filename %t/split/with-normal-import.swift -I %t/build -code-completion-token=COMPLETE | %FileCheck %s --check-prefix=WITHOUT_SPI
15+
// RUN: %target-swift-ide-test -code-completion -completion-cache-path %t/cc-cache -source-filename %t/split/with-spi-import.swift -I %t/build -code-completion-token=COMPLETE | %FileCheck %s --check-prefix=WITH_SPI
16+
17+
// WITH_SPI: Begin completions
18+
// WITH_SPI-DAG: Decl[FreeFunction]/OtherModule[pck]: apiFunc()[#Void#]; name=apiFunc()
19+
// WITH_SPI-DAG: Decl[FreeFunction]/OtherModule[pck]: spiFunc()[#Void#]; name=spiFunc()
20+
// WITH_SPI: End completions
21+
22+
// WITHOUT_SPI: Begin completions
23+
// WITHOUT_SPI-NOT: spiFunc
24+
// WITHOUT_SPI-DAG: Decl[FreeFunction]/OtherModule[pck]: apiFunc()[#Void#]; name=apiFunc()
25+
// WITHOUT_SPI-NOT: spiFunc
26+
// WITHOUT_SPI: End completions
27+
28+
29+
// BEGIN pck.swift
30+
31+
public func apiFunc() {}
32+
33+
@_spi(MySPI)
34+
public func spiFunc() {}
35+
36+
// BEGIN with-spi-import.swift
37+
38+
@_spi(MySPI) import pck
39+
40+
func test() {
41+
#^COMPLETE^#
42+
}
43+
44+
// BEGIN with-normal-import.swift
45+
46+
import pck
47+
48+
func test() {
49+
#^COMPLETE^#
50+
}

0 commit comments

Comments
 (0)