[IDE] Remove extension binding logic from typeCheckContextAt

Now that we correctly bind extensions after mutating the AST, this
is no longer necessary.
This commit is contained in:
Hamish Knight
2025-08-10 23:49:03 +01:00
parent acf6375d46
commit deecd46e43
5 changed files with 8 additions and 51 deletions

View File

@@ -1485,12 +1485,12 @@ void CodeCompletionCallbacksImpl::typeCheckWithLookup(
ASTNode Call = CallExpr::create(
CurDeclContext->getASTContext(), AttrWithCompletion->getTypeExpr(),
AttrWithCompletion->getArgs(), /*implicit=*/true);
typeCheckContextAt(
swift::typeCheckASTNodeAtLoc(
TypeCheckASTNodeAtLocContext::node(CurDeclContext, Call),
CompletionLoc);
}
} else {
typeCheckContextAt(
swift::typeCheckASTNodeAtLoc(
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
CompletionLoc);
}
@@ -1551,8 +1551,9 @@ void CodeCompletionCallbacksImpl::postfixCompletion(SourceLoc CompletionLoc,
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
Context.CompletionCallback, &Lookup);
typeCheckContextAt(TypeCheckASTNodeAtLocContext::node(CurDeclContext, AE),
CompletionLoc);
swift::typeCheckASTNodeAtLoc(
TypeCheckASTNodeAtLocContext::node(CurDeclContext, AE),
CompletionLoc);
Lookup.collectResults(/*IsLabeledTrailingClosure=*/true, CompletionLoc,
CurDeclContext, CompletionContext);
}
@@ -1711,7 +1712,7 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
if (Kind != CompletionKind::TypeSimpleWithDot) {
// Type member completion does not need a type-checked AST.
typeCheckContextAt(
swift::typeCheckASTNodeAtLoc(
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
ParsedExpr ? ParsedExpr->getLoc()
: CurDeclContext->getASTContext()

View File

@@ -109,7 +109,7 @@ void ConformingMethodListCallbacks::doneParsing(SourceFile *SrcFile) {
{
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
Context.CompletionCallback, &TypeCheckCallback);
typeCheckContextAt(
swift::typeCheckASTNodeAtLoc(
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
CCExpr->getLoc());
}

View File

@@ -40,45 +40,6 @@
using namespace swift;
using namespace ide;
//===----------------------------------------------------------------------===//
// typeCheckContextAt(DeclContext, SourceLoc)
//===----------------------------------------------------------------------===//
void swift::ide::typeCheckContextAt(TypeCheckASTNodeAtLocContext TypeCheckCtx,
SourceLoc Loc) {
// Make sure the extension has been bound.
auto DC = TypeCheckCtx.getDeclContext();
// Even if the extension is invalid (e.g. nested in a function or another
// type), we want to know the "intended nominal" of the extension so that
// we can know the type of 'Self'.
SmallVector<ExtensionDecl *, 1> extensions;
for (auto typeCtx = DC->getInnermostTypeContext(); typeCtx != nullptr;
typeCtx = typeCtx->getParent()->getInnermostTypeContext()) {
if (auto *ext = dyn_cast<ExtensionDecl>(typeCtx))
extensions.push_back(ext);
}
while (!extensions.empty()) {
extensions.back()->computeExtendedNominal();
extensions.pop_back();
}
// If the completion happens in the inheritance clause of the extension,
// 'DC' is the parent of the extension. We need to iterate the top level
// decls to find it. In theory, we don't need the extended nominal in the
// inheritance clause, but ASTScope lookup requires that. We don't care
// unless 'DC' is not 'SourceFile' because non-toplevel extensions are
// 'canNeverBeBound()' anyway.
if (auto *SF = dyn_cast<SourceFile>(DC)) {
auto &SM = DC->getASTContext().SourceMgr;
for (auto *decl : SF->getTopLevelDecls())
if (auto *ext = dyn_cast<ExtensionDecl>(decl))
if (SM.rangeContainsTokenLoc(ext->getSourceRange(), Loc))
ext->computeExtendedNominal();
}
swift::typeCheckASTNodeAtLoc(TypeCheckCtx, Loc);
}
//===----------------------------------------------------------------------===//
// findParsedExpr(DeclContext, Expr)
//===----------------------------------------------------------------------===//

View File

@@ -28,11 +28,6 @@ class ValueDecl;
namespace ide {
enum class SemanticContextKind : uint8_t;
/// Type check parent contexts of the given decl context, and the body of the
/// given context until \c Loc if the context is a function body.
void typeCheckContextAt(TypeCheckASTNodeAtLocContext TypeCheckCtx,
SourceLoc Loc);
/// From \p DC, find and returns the outer most expression which source range is
/// exact the same as \p TargetRange. Returns \c nullptr if not found.
Expr *findParsedExpr(const DeclContext *DC, SourceRange TargetRange);

View File

@@ -119,7 +119,7 @@ void ContextInfoCallbacks::doneParsing(SourceFile *SrcFile) {
{
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
Context.CompletionCallback, &TypeCheckCallback);
typeCheckContextAt(
swift::typeCheckASTNodeAtLoc(
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
ParsedExpr->getLoc());
}