Skip to content

Commit 5e27e83

Browse files
authored
Merge pull request #83613 from hamishknight/next-step
[IDE] Perform extension binding after AST mutation
2 parents 2caa726 + deecd46 commit 5e27e83

16 files changed

+95
-77
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5389,6 +5389,25 @@ class DefaultIsolationInSourceFileRequest
53895389
bool isCached() const { return true; }
53905390
};
53915391

5392+
/// A request that allows IDE inspection to lazily kick extension binding after
5393+
/// it has finished mutating the AST. This will eventually be subsumed when we
5394+
/// properly requestify extension binding.
5395+
class BindExtensionsForIDEInspectionRequest
5396+
: public SimpleRequest<BindExtensionsForIDEInspectionRequest,
5397+
evaluator::SideEffect(ModuleDecl *),
5398+
RequestFlags::Cached> {
5399+
public:
5400+
using SimpleRequest::SimpleRequest;
5401+
5402+
private:
5403+
friend SimpleRequest;
5404+
5405+
evaluator::SideEffect evaluate(Evaluator &evaluator, ModuleDecl *M) const;
5406+
5407+
public:
5408+
bool isCached() const { return true; }
5409+
};
5410+
53925411
class ModuleHasTypeCheckerPerformanceHacksEnabledRequest
53935412
: public SimpleRequest<ModuleHasTypeCheckerPerformanceHacksEnabledRequest,
53945413
bool(const ModuleDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,10 @@ SWIFT_REQUEST(TypeChecker, DefaultIsolationInSourceFileRequest,
641641
std::optional<DefaultIsolation>(const SourceFile *),
642642
Cached, NoLocationInfo)
643643

644+
SWIFT_REQUEST(TypeChecker, BindExtensionsForIDEInspectionRequest,
645+
evaluator::SideEffect(ModuleDecl *),
646+
Cached, NoLocationInfo)
647+
644648
SWIFT_REQUEST(TypeChecker, ModuleHasTypeCheckerPerformanceHacksEnabledRequest,
645649
bool(const ModuleDecl *),
646650
Cached, NoLocationInfo)

include/swift/Frontend/Frontend.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,11 @@ class CompilerInstance {
787787
/// Parses and type-checks all input files.
788788
void performSema();
789789

790+
/// Loads any access notes for the main module.
791+
///
792+
/// FIXME: This should be requestified.
793+
void loadAccessNotesIfNeeded();
794+
790795
/// Parses and performs import resolution on all input files.
791796
///
792797
/// This is similar to a parse-only invocation, but module imports will also

lib/Frontend/Frontend.cpp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,33 +1544,40 @@ void CompilerInstance::setMainModule(ModuleDecl *newMod) {
15441544
Context->MainModule = newMod;
15451545
}
15461546

1547+
void CompilerInstance::loadAccessNotesIfNeeded() {
1548+
if (Invocation.getFrontendOptions().AccessNotesPath.empty())
1549+
return;
1550+
1551+
auto *mainModule = getMainModule();
1552+
1553+
auto accessNotesPath = Invocation.getFrontendOptions().AccessNotesPath;
1554+
1555+
auto bufferOrError =
1556+
swift::vfs::getFileOrSTDIN(getFileSystem(), accessNotesPath);
1557+
if (bufferOrError) {
1558+
int sourceID = SourceMgr.addNewSourceBuffer(std::move(bufferOrError.get()));
1559+
auto buffer = SourceMgr.getLLVMSourceMgr().getMemoryBuffer(sourceID);
1560+
1561+
if (auto accessNotesFile = AccessNotesFile::load(*Context, buffer))
1562+
mainModule->getAccessNotes() = *accessNotesFile;
1563+
} else {
1564+
Diagnostics.diagnose(SourceLoc(), diag::access_notes_file_io_error,
1565+
accessNotesPath, bufferOrError.getError().message());
1566+
}
1567+
}
1568+
15471569
bool CompilerInstance::performParseAndResolveImportsOnly() {
15481570
FrontendStatsTracer tracer(getStatsReporter(), "parse-and-resolve-imports");
15491571

1550-
auto *mainModule = getMainModule();
1572+
// NOTE: Do not add new logic to this function, use the request evaluator to
1573+
// lazily evaluate instead. Once the below computations are requestified we
1574+
// ought to be able to remove this function.
15511575

15521576
// Load access notes.
1553-
if (!Invocation.getFrontendOptions().AccessNotesPath.empty()) {
1554-
auto accessNotesPath = Invocation.getFrontendOptions().AccessNotesPath;
1555-
1556-
auto bufferOrError =
1557-
swift::vfs::getFileOrSTDIN(getFileSystem(), accessNotesPath);
1558-
if (bufferOrError) {
1559-
int sourceID =
1560-
SourceMgr.addNewSourceBuffer(std::move(bufferOrError.get()));
1561-
auto buffer =
1562-
SourceMgr.getLLVMSourceMgr().getMemoryBuffer(sourceID);
1563-
1564-
if (auto accessNotesFile = AccessNotesFile::load(*Context, buffer))
1565-
mainModule->getAccessNotes() = *accessNotesFile;
1566-
}
1567-
else {
1568-
Diagnostics.diagnose(SourceLoc(), diag::access_notes_file_io_error,
1569-
accessNotesPath, bufferOrError.getError().message());
1570-
}
1571-
}
1577+
loadAccessNotesIfNeeded();
15721578

15731579
// Resolve imports for all the source files in the module.
1580+
auto *mainModule = getMainModule();
15741581
performImportResolution(mainModule);
15751582

15761583
bindExtensions(*mainModule);

lib/IDE/CodeCompletion.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,12 +1485,12 @@ void CodeCompletionCallbacksImpl::typeCheckWithLookup(
14851485
ASTNode Call = CallExpr::create(
14861486
CurDeclContext->getASTContext(), AttrWithCompletion->getTypeExpr(),
14871487
AttrWithCompletion->getArgs(), /*implicit=*/true);
1488-
typeCheckContextAt(
1488+
swift::typeCheckASTNodeAtLoc(
14891489
TypeCheckASTNodeAtLocContext::node(CurDeclContext, Call),
14901490
CompletionLoc);
14911491
}
14921492
} else {
1493-
typeCheckContextAt(
1493+
swift::typeCheckASTNodeAtLoc(
14941494
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
14951495
CompletionLoc);
14961496
}
@@ -1551,8 +1551,9 @@ void CodeCompletionCallbacksImpl::postfixCompletion(SourceLoc CompletionLoc,
15511551

15521552
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
15531553
Context.CompletionCallback, &Lookup);
1554-
typeCheckContextAt(TypeCheckASTNodeAtLocContext::node(CurDeclContext, AE),
1555-
CompletionLoc);
1554+
swift::typeCheckASTNodeAtLoc(
1555+
TypeCheckASTNodeAtLocContext::node(CurDeclContext, AE),
1556+
CompletionLoc);
15561557
Lookup.collectResults(/*IsLabeledTrailingClosure=*/true, CompletionLoc,
15571558
CurDeclContext, CompletionContext);
15581559
}
@@ -1711,7 +1712,7 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
17111712

17121713
if (Kind != CompletionKind::TypeSimpleWithDot) {
17131714
// Type member completion does not need a type-checked AST.
1714-
typeCheckContextAt(
1715+
swift::typeCheckASTNodeAtLoc(
17151716
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
17161717
ParsedExpr ? ParsedExpr->getLoc()
17171718
: CurDeclContext->getASTContext()

lib/IDE/ConformingMethodList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void ConformingMethodListCallbacks::doneParsing(SourceFile *SrcFile) {
109109
{
110110
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
111111
Context.CompletionCallback, &TypeCheckCallback);
112-
typeCheckContextAt(
112+
swift::typeCheckASTNodeAtLoc(
113113
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
114114
CCExpr->getLoc());
115115
}

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -40,45 +40,6 @@
4040
using namespace swift;
4141
using namespace ide;
4242

43-
//===----------------------------------------------------------------------===//
44-
// typeCheckContextAt(DeclContext, SourceLoc)
45-
//===----------------------------------------------------------------------===//
46-
47-
void swift::ide::typeCheckContextAt(TypeCheckASTNodeAtLocContext TypeCheckCtx,
48-
SourceLoc Loc) {
49-
// Make sure the extension has been bound.
50-
auto DC = TypeCheckCtx.getDeclContext();
51-
// Even if the extension is invalid (e.g. nested in a function or another
52-
// type), we want to know the "intended nominal" of the extension so that
53-
// we can know the type of 'Self'.
54-
SmallVector<ExtensionDecl *, 1> extensions;
55-
for (auto typeCtx = DC->getInnermostTypeContext(); typeCtx != nullptr;
56-
typeCtx = typeCtx->getParent()->getInnermostTypeContext()) {
57-
if (auto *ext = dyn_cast<ExtensionDecl>(typeCtx))
58-
extensions.push_back(ext);
59-
}
60-
while (!extensions.empty()) {
61-
extensions.back()->computeExtendedNominal();
62-
extensions.pop_back();
63-
}
64-
65-
// If the completion happens in the inheritance clause of the extension,
66-
// 'DC' is the parent of the extension. We need to iterate the top level
67-
// decls to find it. In theory, we don't need the extended nominal in the
68-
// inheritance clause, but ASTScope lookup requires that. We don't care
69-
// unless 'DC' is not 'SourceFile' because non-toplevel extensions are
70-
// 'canNeverBeBound()' anyway.
71-
if (auto *SF = dyn_cast<SourceFile>(DC)) {
72-
auto &SM = DC->getASTContext().SourceMgr;
73-
for (auto *decl : SF->getTopLevelDecls())
74-
if (auto *ext = dyn_cast<ExtensionDecl>(decl))
75-
if (SM.rangeContainsTokenLoc(ext->getSourceRange(), Loc))
76-
ext->computeExtendedNominal();
77-
}
78-
79-
swift::typeCheckASTNodeAtLoc(TypeCheckCtx, Loc);
80-
}
81-
8243
//===----------------------------------------------------------------------===//
8344
// findParsedExpr(DeclContext, Expr)
8445
//===----------------------------------------------------------------------===//

lib/IDE/ExprContextAnalysis.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ class ValueDecl;
2828
namespace ide {
2929
enum class SemanticContextKind : uint8_t;
3030

31-
/// Type check parent contexts of the given decl context, and the body of the
32-
/// given context until \c Loc if the context is a function body.
33-
void typeCheckContextAt(TypeCheckASTNodeAtLocContext TypeCheckCtx,
34-
SourceLoc Loc);
35-
3631
/// From \p DC, find and returns the outer most expression which source range is
3732
/// exact the same as \p TargetRange. Returns \c nullptr if not found.
3833
Expr *findParsedExpr(const DeclContext *DC, SourceRange TargetRange);

lib/IDE/REPLCodeCompletion.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
256256

257257
auto &newSF = newModule->getMainSourceFile();
258258
performImportResolution(newSF);
259-
bindExtensions(*newModule);
260259

261260
performIDEInspectionSecondPass(newSF, *CompletionCallbacksFactory);
262261

lib/IDE/TypeContextInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void ContextInfoCallbacks::doneParsing(SourceFile *SrcFile) {
119119
{
120120
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
121121
Context.CompletionCallback, &TypeCheckCallback);
122-
typeCheckContextAt(
122+
swift::typeCheckASTNodeAtLoc(
123123
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
124124
ParsedExpr->getLoc());
125125
}

0 commit comments

Comments
 (0)