Skip to content

Commit 9debb38

Browse files
Merge pull request #20525 from aschwaighofer/code_completion_private_imports
Make sure the code completion takes both private imports and testable
2 parents 9d10068 + 49cdab2 commit 9debb38

File tree

7 files changed

+66
-15
lines changed

7 files changed

+66
-15
lines changed

include/swift/AST/Module.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,18 @@ class SourceFile final : public FileUnit {
990990

991991
void addImports(ArrayRef<ImportedModuleDesc> IM);
992992

993-
bool hasTestableOrPrivateImport(AccessLevel accessLevel, const ValueDecl *ofDecl) const;
993+
enum ImportQueryKind {
994+
/// Return the results for testable or private imports.
995+
TestableAndPrivate,
996+
/// Return the results only for testable imports.
997+
TestableOnly,
998+
/// Return the results only for private imports.
999+
PrivateOnly
1000+
};
1001+
1002+
bool
1003+
hasTestableOrPrivateImport(AccessLevel accessLevel, const ValueDecl *ofDecl,
1004+
ImportQueryKind kind = TestableAndPrivate) const;
9941005

9951006
void clearLookupCache();
9961007

include/swift/IDE/CodeCompletionCache.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class CodeCompletionCache {
4141
std::vector<std::string> AccessPath;
4242
bool ResultsHaveLeadingDot;
4343
bool ForTestableLookup;
44+
bool ForPrivateImportLookup;
4445
bool CodeCompleteInitsInPostfixExpr;
4546

4647
friend bool operator==(const Key &LHS, const Key &RHS) {
@@ -49,6 +50,7 @@ class CodeCompletionCache {
4950
LHS.AccessPath == RHS.AccessPath &&
5051
LHS.ResultsHaveLeadingDot == RHS.ResultsHaveLeadingDot &&
5152
LHS.ForTestableLookup == RHS.ForTestableLookup &&
53+
LHS.ForPrivateImportLookup == RHS.ForPrivateImportLookup &&
5254
LHS.CodeCompleteInitsInPostfixExpr == RHS.CodeCompleteInitsInPostfixExpr;
5355
}
5456
};
@@ -106,10 +108,10 @@ template<>
106108
struct DenseMapInfo<swift::ide::CodeCompletionCache::Key> {
107109
using KeyTy = swift::ide::CodeCompletionCache::Key;
108110
static inline KeyTy getEmptyKey() {
109-
return KeyTy{"", "", {}, false, false, false};
111+
return KeyTy{"", "", {}, false, false, false, false};
110112
}
111113
static inline KeyTy getTombstoneKey() {
112-
return KeyTy{"", "", {}, true, false, false};
114+
return KeyTy{"", "", {}, true, false, false, false};
113115
}
114116
static unsigned getHashValue(const KeyTy &Val) {
115117
size_t H = 0;
@@ -119,6 +121,7 @@ struct DenseMapInfo<swift::ide::CodeCompletionCache::Key> {
119121
H ^= std::hash<std::string>()(Piece);
120122
H ^= std::hash<bool>()(Val.ResultsHaveLeadingDot);
121123
H ^= std::hash<bool>()(Val.ForTestableLookup);
124+
H ^= std::hash<bool>()(Val.ForPrivateImportLookup);
122125
return static_cast<unsigned>(H);
123126
}
124127
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {

lib/AST/Module.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,8 @@ void SourceFile::addImports(ArrayRef<ImportedModuleDesc> IM) {
13891389
}
13901390

13911391
bool SourceFile::hasTestableOrPrivateImport(
1392-
AccessLevel accessLevel, const swift::ValueDecl *ofDecl) const {
1392+
AccessLevel accessLevel, const swift::ValueDecl *ofDecl,
1393+
SourceFile::ImportQueryKind queryKind) const {
13931394
auto *module = ofDecl->getModuleContext();
13941395
switch (accessLevel) {
13951396
case AccessLevel::Internal:
@@ -1399,10 +1400,19 @@ bool SourceFile::hasTestableOrPrivateImport(
13991400
// decls).
14001401
return std::any_of(
14011402
Imports.begin(), Imports.end(),
1402-
[module](ImportedModuleDesc desc) -> bool {
1403-
return desc.module.second == module &&
1404-
(desc.importOptions.contains(ImportFlags::PrivateImport) ||
1405-
desc.importOptions.contains(ImportFlags::Testable));
1403+
[module, queryKind](ImportedModuleDesc desc) -> bool {
1404+
if (queryKind == ImportQueryKind::TestableAndPrivate)
1405+
return desc.module.second == module &&
1406+
(desc.importOptions.contains(ImportFlags::PrivateImport) ||
1407+
desc.importOptions.contains(ImportFlags::Testable));
1408+
else if (queryKind == ImportQueryKind::TestableOnly)
1409+
return desc.module.second == module &&
1410+
desc.importOptions.contains(ImportFlags::Testable);
1411+
else {
1412+
assert(queryKind == ImportQueryKind::PrivateOnly);
1413+
return desc.module.second == module &&
1414+
desc.importOptions.contains(ImportFlags::PrivateImport);
1415+
}
14061416
});
14071417
case AccessLevel::Open:
14081418
return true;
@@ -1412,6 +1422,9 @@ bool SourceFile::hasTestableOrPrivateImport(
14121422
break;
14131423
}
14141424

1425+
if (queryKind == ImportQueryKind::TestableOnly)
1426+
return false;
1427+
14151428
auto *DC = ofDecl->getDeclContext();
14161429
if (!DC)
14171430
return false;

lib/IDE/CodeCompletion.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5946,12 +5946,15 @@ void CodeCompletionCallbacksImpl::doneParsing() {
59465946
if (!ModuleFilename.empty()) {
59475947
auto &Ctx = TheModule->getASTContext();
59485948
CodeCompletionCache::Key K{
5949-
ModuleFilename,
5950-
TheModule->getName().str(),
5951-
AccessPath,
5952-
Request.NeedLeadingDot,
5953-
SF.hasTestableOrPrivateImport(AccessLevel::Internal, TheModule),
5954-
Ctx.LangOpts.CodeCompleteInitsInPostfixExpr};
5949+
ModuleFilename, TheModule->getName().str(), AccessPath,
5950+
Request.NeedLeadingDot,
5951+
SF.hasTestableOrPrivateImport(
5952+
AccessLevel::Internal, TheModule,
5953+
SourceFile::ImportQueryKind::TestableOnly),
5954+
SF.hasTestableOrPrivateImport(
5955+
AccessLevel::Internal, TheModule,
5956+
SourceFile::ImportQueryKind::PrivateOnly),
5957+
Ctx.LangOpts.CodeCompleteInitsInPostfixExpr};
59555958

59565959
using PairType = llvm::DenseSet<swift::ide::CodeCompletionCache::Key,
59575960
llvm::DenseMapInfo<CodeCompletionCache::Key>>::iterator;

lib/IDE/CodeCompletionCache.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ static void writeCachedModule(llvm::raw_ostream &out,
312312
OSS << p << "\0";
313313
OSSLE.write(K.ResultsHaveLeadingDot);
314314
OSSLE.write(K.ForTestableLookup);
315+
OSSLE.write(K.ForPrivateImportLookup);
315316
OSSLE.write(K.CodeCompleteInitsInPostfixExpr);
316317
LE.write(static_cast<uint32_t>(OSS.tell())); // Size of debug info
317318
out.write(OSS.str().data(), OSS.str().size()); // Debug info blob
@@ -423,6 +424,7 @@ static std::string getName(StringRef cacheDirectory,
423424
// name[-dot][-testable][-inits]
424425
OSS << (K.ResultsHaveLeadingDot ? "-dot" : "")
425426
<< (K.ForTestableLookup ? "-testable" : "")
427+
<< (K.ForPrivateImportLookup ? "-private" : "")
426428
<< (K.CodeCompleteInitsInPostfixExpr ? "-inits" : "");
427429

428430
// name[-access-path-components]
@@ -488,7 +490,8 @@ OnDiskCodeCompletionCache::getFromFile(StringRef filename) {
488490
return None;
489491

490492
// Make up a key for readCachedModule.
491-
CodeCompletionCache::Key K{filename, "<module-name>", {}, false, false, false};
493+
CodeCompletionCache::Key K{filename, "<module-name>", {}, false,
494+
false, false, false};
492495

493496
// Read the cached results.
494497
auto V = CodeCompletionCache::createValue();

test/IDE/complete_cache.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,20 @@
3939
// Check the individual cache item.
4040
// RUN: %target-swift-ide-test -dump-completion-cache %t.ccp/macros-dot-* | %FileCheck %s -check-prefix=CLANG_QUAL_MACROS_2
4141

42+
// Qualified private with dot.
43+
// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_STRING -completion-cache-path=%t.ccp > %t.string.ccp1.compl.txt
44+
// RUN: %FileCheck %s -check-prefix=CLANG_QUAL_STRING < %t.string.ccp1.compl.txt
45+
46+
4247
// Ensure the testable import showed up mangled correctly.
4348
// RUN: ls %t.ccp/Darwin-testable*
49+
// RUN: ls %t.ccp/AppKit-private*
4450
// REQUIRES: executable_test
4551

4652
import macros
4753
import ctypes
4854
@testable import Darwin
55+
@_private(sourceFile: "AppKit.swift") import AppKit
4956

5057
// CLANG_CTYPES: Begin completions
5158
// CLANG_CTYPES-DAG: Decl[Struct]/OtherModule[ctypes]/keyword[Foo1, Struct1]: FooStruct1[#FooStruct1#]{{; name=.+$}}
@@ -106,3 +113,10 @@ func testCompleteModuleQualifiedMacros2() {
106113
// CLANG_QUAL_MACROS_2-DAG: Decl[GlobalVar]/OtherModule[macros]: .VERSION_STRING[#String#]{{; name=.+$}}
107114
// CLANG_QUAL_MACROS_2: End completions
108115
}
116+
117+
func testPrivate() {
118+
String.#^CLANG_QUAL_STRING^#
119+
// CLANG_QUAL_STRING: Begin completions
120+
// CLANG_QUAL_STRING: name=someMethod()
121+
// CLANG_QUAL_STRING: End completions
122+
}

test/Inputs/clang-importer-sdk/swift-modules/AppKit.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
extension String {
44
public static func someFactoryMethod() -> Int { return 0 }
55
}
6+
7+
extension String {
8+
static func someMethod() -> Int { return 0 }
9+
}

0 commit comments

Comments
 (0)