Skip to content

Commit d3be024

Browse files
committed
[IDE] Introduce ReadyForTypeCheckingCallback
This avoids the layering violation of calling `bindExtensions` from parser code.
1 parent 17fe3de commit d3be024

File tree

8 files changed

+76
-29
lines changed

8 files changed

+76
-29
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CodeCompletionDiagnostics.h"
1515
#include "CodeCompletionResultBuilder.h"
1616
#include "ExprContextAnalysis.h"
17+
#include "ReadyForTypeCheckingCallback.h"
1718
#include "swift/AST/ASTPrinter.h"
1819
#include "swift/AST/ASTWalker.h"
1920
#include "swift/AST/Comment.h"
@@ -105,7 +106,7 @@ std::string swift::ide::removeCodeCompletionTokens(
105106
namespace {
106107

107108
class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
108-
public DoneParsingCallback {
109+
public ReadyForTypeCheckingCallback {
109110
CodeCompletionContext &CompletionContext;
110111
CodeCompletionConsumer &Consumer;
111112
CodeCompletionExpr *CodeCompleteTokenExpr = nullptr;
@@ -214,8 +215,8 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
214215
CodeCompletionCallbacksImpl(Parser &P,
215216
CodeCompletionContext &CompletionContext,
216217
CodeCompletionConsumer &Consumer)
217-
: CodeCompletionCallbacks(P), DoneParsingCallback(),
218-
CompletionContext(CompletionContext), Consumer(Consumer) {}
218+
: CodeCompletionCallbacks(P), CompletionContext(CompletionContext),
219+
Consumer(Consumer) {}
219220

220221
void setAttrTargetDeclKind(std::optional<DeclKind> DK) override {
221222
if (DK == DeclKind::PatternBinding)
@@ -290,7 +291,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
290291
void completeTypeAttrInheritanceBeginning() override;
291292
void completeOptionalBinding() override;
292293

293-
void doneParsing(SourceFile *SrcFile) override;
294+
void readyForTypeChecking(SourceFile *SrcFile) override;
294295

295296
private:
296297
void addKeywords(CodeCompletionResultSink &Sink, bool MaybeFuncBody);
@@ -1622,7 +1623,7 @@ void CodeCompletionCallbacksImpl::afterPoundCompletion(SourceLoc CompletionLoc,
16221623
Consumer.handleResults(CompletionContext);
16231624
}
16241625

1625-
void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
1626+
void CodeCompletionCallbacksImpl::readyForTypeChecking(SourceFile *SrcFile) {
16261627
CompletionContext.CodeCompletionKind = Kind;
16271628

16281629
if (Kind == CompletionKind::None) {

lib/IDE/ConformingMethodList.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "swift/IDE/ConformingMethodList.h"
1414
#include "ExprContextAnalysis.h"
15+
#include "ReadyForTypeCheckingCallback.h"
1516
#include "swift/AST/ASTDemangler.h"
1617
#include "swift/AST/ConformanceLookup.h"
1718
#include "swift/AST/GenericEnvironment.h"
@@ -20,8 +21,8 @@
2021
#include "swift/Basic/Assertions.h"
2122
#include "swift/IDE/TypeCheckCompletionCallback.h"
2223
#include "swift/Parse/IDEInspectionCallbacks.h"
23-
#include "swift/Sema/IDETypeChecking.h"
2424
#include "swift/Sema/ConstraintSystem.h"
25+
#include "swift/Sema/IDETypeChecking.h"
2526
#include "clang/AST/Attr.h"
2627
#include "clang/AST/Decl.h"
2728

@@ -30,7 +31,7 @@ using namespace ide;
3031

3132
namespace {
3233
class ConformingMethodListCallbacks : public CodeCompletionCallbacks,
33-
public DoneParsingCallback {
34+
public ReadyForTypeCheckingCallback {
3435
ArrayRef<const char *> ExpectedTypeNames;
3536
ConformingMethodListConsumer &Consumer;
3637
SourceLoc Loc;
@@ -45,16 +46,16 @@ class ConformingMethodListCallbacks : public CodeCompletionCallbacks,
4546
ConformingMethodListCallbacks(Parser &P,
4647
ArrayRef<const char *> ExpectedTypeNames,
4748
ConformingMethodListConsumer &Consumer)
48-
: CodeCompletionCallbacks(P), DoneParsingCallback(),
49-
ExpectedTypeNames(ExpectedTypeNames), Consumer(Consumer) {}
49+
: CodeCompletionCallbacks(P), ExpectedTypeNames(ExpectedTypeNames),
50+
Consumer(Consumer) {}
5051

5152
// Only handle callbacks for suffix completions.
5253
// {
5354
void completeDotExpr(CodeCompletionExpr *E, SourceLoc DotLoc) override;
5455
void completePostfixExpr(CodeCompletionExpr *E, bool hasSpace) override;
5556
// }
5657

57-
void doneParsing(SourceFile *SrcFile) override;
58+
void readyForTypeChecking(SourceFile *SrcFile) override;
5859
};
5960

6061
void ConformingMethodListCallbacks::completeDotExpr(CodeCompletionExpr *E,
@@ -101,7 +102,7 @@ class ConformingMethodListCallback : public TypeCheckCompletionCallback {
101102
ArrayRef<Result> getResults() const { return Results; }
102103
};
103104

104-
void ConformingMethodListCallbacks::doneParsing(SourceFile *SrcFile) {
105+
void ConformingMethodListCallbacks::readyForTypeChecking(SourceFile *SrcFile) {
105106
if (!CCExpr || !CCExpr->getBase())
106107
return;
107108

lib/IDE/CursorInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "swift/IDE/CursorInfo.h"
1414
#include "ExprContextAnalysis.h"
15+
#include "ReadyForTypeCheckingCallback.h"
1516
#include "swift/AST/ASTDemangler.h"
1617
#include "swift/AST/GenericEnvironment.h"
1718
#include "swift/AST/NameLookup.h"
@@ -374,14 +375,14 @@ class CursorInfoTypeCheckSolutionCallback : public TypeCheckCompletionCallback {
374375

375376
// MARK: - CursorInfoDoneParsingCallback
376377

377-
class CursorInfoDoneParsingCallback : public DoneParsingCallback {
378+
class CursorInfoDoneParsingCallback : public ReadyForTypeCheckingCallback {
378379
CursorInfoConsumer &Consumer;
379380
SourceLoc RequestedLoc;
380381

381382
public:
382383
CursorInfoDoneParsingCallback(Parser &P, CursorInfoConsumer &Consumer,
383384
SourceLoc RequestedLoc)
384-
: DoneParsingCallback(), Consumer(Consumer), RequestedLoc(RequestedLoc) {}
385+
: Consumer(Consumer), RequestedLoc(RequestedLoc) {}
385386

386387
private:
387388
/// Shared core of `getExprResult` and `getDeclResult`.
@@ -489,7 +490,7 @@ class CursorInfoDoneParsingCallback : public DoneParsingCallback {
489490
SrcFile, Finder);
490491
}
491492

492-
void doneParsing(SourceFile *SrcFile) override {
493+
void readyForTypeChecking(SourceFile *SrcFile) override {
493494
if (!SrcFile) {
494495
return;
495496
}

lib/IDE/IDETypeChecking.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/Sema/IDETypeChecking.h"
14+
#include "ReadyForTypeCheckingCallback.h"
1415
#include "swift/AST/ASTContext.h"
1516
#include "swift/AST/ASTDemangler.h"
1617
#include "swift/AST/ASTPrinter.h"
@@ -32,9 +33,11 @@
3233
#include "swift/IDE/SourceEntityWalker.h"
3334
#include "swift/Parse/Lexer.h"
3435
#include "swift/Sema/IDETypeCheckingRequests.h"
36+
#include "swift/Subsystems.h"
3537
#include "llvm/ADT/SmallVector.h"
3638

3739
using namespace swift;
40+
using namespace ide;
3841

3942
void swift::getTopLevelDeclsForDisplay(ModuleDecl *M,
4043
SmallVectorImpl<Decl *> &Results,
@@ -1028,3 +1031,11 @@ swift::getShorthandShadows(LabeledConditionalStmt *CondStmt, DeclContext *DC) {
10281031
}
10291032
return Result;
10301033
}
1034+
1035+
void ReadyForTypeCheckingCallback::doneParsing(SourceFile *SrcFile) {
1036+
// Import resolution will have already been done by IDEInspectionInstance,
1037+
// we need to bind extensions here though since IDEInspectionSecondPassRequest
1038+
// can mutate the AST.
1039+
bindExtensions(*SrcFile->getParentModule());
1040+
readyForTypeChecking(SrcFile);
1041+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===--- ReadyForTypeCheckingCallback.h -----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_IDE_READYFORTYPECHECKINGCALLBACK_H
14+
#define SWIFT_IDE_READYFORTYPECHECKINGCALLBACK_H
15+
16+
#include "swift/Parse/IDEInspectionCallbacks.h"
17+
18+
namespace swift {
19+
namespace ide {
20+
21+
/// IDE inspection callback that is invoked once the resulting AST is ready
22+
/// for type-checking work.
23+
class ReadyForTypeCheckingCallback : public DoneParsingCallback {
24+
public:
25+
virtual ~ReadyForTypeCheckingCallback() {}
26+
27+
virtual void doneParsing(SourceFile *SrcFile) override;
28+
29+
/// Called when the AST has been parsed and had its imports resolved and
30+
/// extensions bound.
31+
virtual void readyForTypeChecking(SourceFile *SrcFile) = 0;
32+
};
33+
34+
} // namespace ide
35+
} // namespace swift
36+
37+
#endif // SWIFT_IDE_READYFORTYPECHECKINGCALLBACK_H

lib/IDE/SignatureHelp.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/IDE/SignatureHelp.h"
14+
#include "ReadyForTypeCheckingCallback.h"
1415
#include "swift/IDE/ArgumentCompletion.h"
1516
#include "swift/Sema/IDETypeChecking.h"
1617

@@ -20,30 +21,30 @@ using namespace swift::constraints;
2021

2122
namespace {
2223
class SignatureHelpCallbacks : public CodeCompletionCallbacks,
23-
public DoneParsingCallback {
24+
public ReadyForTypeCheckingCallback {
2425
SignatureHelpConsumer &Consumer;
2526
SourceLoc Loc;
2627
CodeCompletionExpr *CCExpr = nullptr;
2728
DeclContext *CurDeclContext = nullptr;
2829

2930
public:
3031
SignatureHelpCallbacks(Parser &P, SignatureHelpConsumer &Consumer)
31-
: CodeCompletionCallbacks(P), DoneParsingCallback(), Consumer(Consumer) {}
32+
: CodeCompletionCallbacks(P), Consumer(Consumer) {}
3233

3334
// Only handle callbacks for argument completions.
3435
// {
3536
void completeCallArg(CodeCompletionExpr *E) override;
3637
// }
3738

38-
void doneParsing(SourceFile *SrcFile) override;
39+
void readyForTypeChecking(SourceFile *SrcFile) override;
3940
};
4041

4142
void SignatureHelpCallbacks::completeCallArg(CodeCompletionExpr *E) {
4243
CurDeclContext = P.CurDeclContext;
4344
CCExpr = E;
4445
}
4546

46-
void SignatureHelpCallbacks::doneParsing(SourceFile *SrcFile) {
47+
void SignatureHelpCallbacks::readyForTypeChecking(SourceFile *SrcFile) {
4748
if (!CCExpr)
4849
return;
4950

lib/IDE/TypeContextInfo.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "swift/IDE/TypeContextInfo.h"
1414
#include "ExprContextAnalysis.h"
15+
#include "ReadyForTypeCheckingCallback.h"
1516
#include "swift/AST/GenericEnvironment.h"
1617
#include "swift/AST/NameLookup.h"
1718
#include "swift/AST/USRGeneration.h"
@@ -27,7 +28,7 @@ using namespace swift;
2728
using namespace ide;
2829

2930
class ContextInfoCallbacks : public CodeCompletionCallbacks,
30-
public DoneParsingCallback {
31+
public ReadyForTypeCheckingCallback {
3132
TypeContextInfoConsumer &Consumer;
3233
SourceLoc Loc;
3334
Expr *ParsedExpr = nullptr;
@@ -37,7 +38,7 @@ class ContextInfoCallbacks : public CodeCompletionCallbacks,
3738

3839
public:
3940
ContextInfoCallbacks(Parser &P, TypeContextInfoConsumer &Consumer)
40-
: CodeCompletionCallbacks(P), DoneParsingCallback(), Consumer(Consumer) {}
41+
: CodeCompletionCallbacks(P), Consumer(Consumer) {}
4142

4243
void completePostfixExprBeginning(CodeCompletionExpr *E) override;
4344
void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
@@ -52,7 +53,7 @@ class ContextInfoCallbacks : public CodeCompletionCallbacks,
5253
void completeUnresolvedMember(CodeCompletionExpr *E,
5354
SourceLoc DotLoc) override;
5455

55-
void doneParsing(SourceFile *SrcFile) override;
56+
void readyForTypeChecking(SourceFile *SrcFile) override;
5657
};
5758

5859
void ContextInfoCallbacks::completePostfixExprBeginning(CodeCompletionExpr *E) {
@@ -111,7 +112,7 @@ class TypeContextInfoCallback : public TypeCheckCompletionCallback {
111112
ArrayRef<Type> getTypes() const { return Types; }
112113
};
113114

114-
void ContextInfoCallbacks::doneParsing(SourceFile *SrcFile) {
115+
void ContextInfoCallbacks::readyForTypeChecking(SourceFile *SrcFile) {
115116
if (!ParsedExpr)
116117
return;
117118

lib/Parse/Parser.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,7 @@ void Parser::performIDEInspectionSecondPassImpl(
210210
assert(!State->hasIDEInspectionDelayedDeclState() &&
211211
"Second pass should not set any code completion info");
212212

213-
auto *SF = DC->getParentSourceFile();
214-
215-
// Bind extensions if needed. This needs to be done here since we may have
216-
// mutated the AST above.
217-
bindExtensions(*SF->getParentModule());
218-
219-
DoneParsingCallback->doneParsing(SF);
213+
DoneParsingCallback->doneParsing(DC->getParentSourceFile());
220214

221215
State->restoreIDEInspectionDelayedDeclState(info);
222216
}

0 commit comments

Comments
 (0)