Skip to content

Commit 2017eed

Browse files
authored
Merge pull request #62366 from ahoppen/ahoppen/solver-based-cursor-info-prep-pt-3
[IDE] Allow typeCheckASTNodeAtLoc to type check declarations
2 parents cc8e28c + fe228a4 commit 2017eed

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,25 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
174174

175175
/// \returns true on success, false on failure.
176176
bool typecheckParsedType() {
177+
// If the type appeared inside an extension, make sure that extension has
178+
// been bound.
179+
auto SF = CurDeclContext->getParentSourceFile();
180+
auto visitTopLevelDecl = [&](Decl *D) {
181+
if (auto ED = dyn_cast<ExtensionDecl>(D)) {
182+
if (ED->getSourceRange().contains(ParsedTypeLoc.getLoc())) {
183+
ED->computeExtendedNominal();
184+
}
185+
}
186+
};
187+
for (auto item : SF->getTopLevelItems()) {
188+
if (auto D = item.dyn_cast<Decl *>()) {
189+
visitTopLevelDecl(D);
190+
}
191+
}
192+
for (auto *D : SF->getHoistedDecls()) {
193+
visitTopLevelDecl(D);
194+
}
195+
177196
assert(ParsedTypeLoc.getTypeRepr() && "should have a TypeRepr");
178197
if (ParsedTypeLoc.wasValidated() && !ParsedTypeLoc.isError()) {
179198
return true;
@@ -1576,11 +1595,14 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
15761595
return;
15771596

15781597
undoSingleExpressionReturn(CurDeclContext);
1579-
typeCheckContextAt(
1580-
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
1581-
ParsedExpr
1582-
? ParsedExpr->getLoc()
1583-
: CurDeclContext->getASTContext().SourceMgr.getCodeCompletionLoc());
1598+
if (Kind != CompletionKind::TypeIdentifierWithDot) {
1599+
// Type member completion does not need a type-checked AST.
1600+
typeCheckContextAt(
1601+
TypeCheckASTNodeAtLocContext::declContext(CurDeclContext),
1602+
ParsedExpr
1603+
? ParsedExpr->getLoc()
1604+
: CurDeclContext->getASTContext().SourceMgr.getCodeCompletionLoc());
1605+
}
15841606

15851607
// Add keywords even if type checking fails completely.
15861608
addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);

lib/Sema/TypeCheckStmt.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,9 +1933,19 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
19331933
if (!braceCharRange.contains(Loc))
19341934
return Action::SkipChildren(S);
19351935

1936-
// Reset the node found in a parent context.
1937-
if (!brace->isImplicit())
1938-
FoundNode = nullptr;
1936+
// Reset the node found in a parent context if it's not part of this
1937+
// brace statement.
1938+
// We must not reset FoundNode if it's inside thei BraceStmt's source
1939+
// range because the found node could be inside a capture list, which is
1940+
// syntactically part of the brace stmt's range but won't be walked as
1941+
// a child of the brace stmt.
1942+
if (!brace->isImplicit() && FoundNode) {
1943+
auto foundNodeCharRange = Lexer::getCharSourceRangeFromSourceRange(
1944+
SM, FoundNode->getSourceRange());
1945+
if (!braceCharRange.contains(foundNodeCharRange)) {
1946+
FoundNode = nullptr;
1947+
}
1948+
}
19391949

19401950
for (ASTNode &node : brace->getElements()) {
19411951
if (SM.isBeforeInBuffer(Loc, node.getStartLoc()))
@@ -1992,6 +2002,18 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
19922002
PreWalkAction walkToDeclPre(Decl *D) override {
19932003
if (auto *newDC = dyn_cast<DeclContext>(D))
19942004
DC = newDC;
2005+
2006+
if (!SM.isBeforeInBuffer(Loc, D->getStartLoc())) {
2007+
// NOTE: We need to check the character loc here because the target
2008+
// loc can be inside the last token of the node. i.e. interpolated
2009+
// string.
2010+
SourceLoc endLoc = Lexer::getLocForEndOfToken(SM, D->getEndLoc());
2011+
if (!(SM.isBeforeInBuffer(endLoc, Loc) || endLoc == Loc)) {
2012+
if (!isa<TopLevelCodeDecl>(D)) {
2013+
FoundNode = new ASTNode(D);
2014+
}
2015+
}
2016+
}
19952017
return Action::Continue();
19962018
}
19972019

@@ -2005,7 +2027,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
20052027
}
20062028

20072029
// Nothing found at the location, or the decl context does not own the 'Loc'.
2008-
if (finder.isNull())
2030+
if (finder.isNull() || !finder.getDeclContext())
20092031
return true;
20102032

20112033
DeclContext *DC = finder.getDeclContext();

0 commit comments

Comments
 (0)