Skip to content

Commit ebc99c6

Browse files
committed
[CodeCompletion] Separate TypeCheckFunctionBodyAtLocRequest
from TypeCheckFunctionBodyRequest, and only do necessary operations.
1 parent 6c61e60 commit ebc99c6

File tree

6 files changed

+73
-26
lines changed

6 files changed

+73
-26
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -867,14 +867,13 @@ class LazyStoragePropertyRequest :
867867
bool isCached() const { return true; }
868868
};
869869

870-
/// Request to type check the body of the given function up to the given
871-
/// source location.
870+
/// Request to type check the body of the given function.
872871
///
873872
/// Produces true if an error occurred, false otherwise.
874873
/// FIXME: it would be far better to return the type-checked body.
875874
class TypeCheckFunctionBodyRequest :
876875
public SimpleRequest<TypeCheckFunctionBodyRequest,
877-
bool(AbstractFunctionDecl *, SourceLoc),
876+
bool(AbstractFunctionDecl *),
878877
RequestFlags::Cached|RequestFlags::DependencySource> {
879878
public:
880879
using SimpleRequest::SimpleRequest;
@@ -883,9 +882,7 @@ class TypeCheckFunctionBodyRequest :
883882
friend SimpleRequest;
884883

885884
// Evaluation.
886-
bool
887-
evaluate(Evaluator &evaluator, AbstractFunctionDecl *func,
888-
SourceLoc endTypeCheckLoc) const;
885+
bool evaluate(Evaluator &evaluator, AbstractFunctionDecl *func) const;
889886

890887
public:
891888
bool isCached() const { return true; }
@@ -896,6 +893,24 @@ class TypeCheckFunctionBodyRequest :
896893
readDependencySource(const evaluator::DependencyRecorder &) const;
897894
};
898895

896+
/// Request to typecheck a function body element at the given source location.
897+
///
898+
/// Produces true if an error occurred, false otherwise.
899+
class TypeCheckFunctionBodyAtLocRequest
900+
: public SimpleRequest<TypeCheckFunctionBodyAtLocRequest,
901+
bool(AbstractFunctionDecl *, SourceLoc),
902+
RequestFlags::Uncached> {
903+
public:
904+
using SimpleRequest::SimpleRequest;
905+
906+
private:
907+
friend SimpleRequest;
908+
909+
// Evaluation.
910+
bool evaluate(Evaluator &evaluator, AbstractFunctionDecl *func,
911+
SourceLoc Loc) const;
912+
};
913+
899914
/// Request to obtain a list of stored properties in a nominal type.
900915
///
901916
/// This will include backing storage for lazy properties and

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,10 @@ SWIFT_REQUEST(TypeChecker, SynthesizeAccessorRequest,
197197
AccessorDecl *(AbstractStorageDecl *, AccessorKind),
198198
SeparatelyCached, NoLocationInfo)
199199
SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyRequest,
200+
bool(AbstractFunctionDecl *), Cached, NoLocationInfo)
201+
SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyAtLocRequest,
200202
bool(AbstractFunctionDecl *, SourceLoc),
201-
Cached, NoLocationInfo)
203+
Uncached, NoLocationInfo)
202204
SWIFT_REQUEST(TypeChecker, UnderlyingTypeRequest, Type(TypeAliasDecl *),
203205
SeparatelyCached, NoLocationInfo)
204206
SWIFT_REQUEST(TypeChecker, USRGenerationRequest, std::string(const ValueDecl *),

include/swift/Sema/IDETypeChecking.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ namespace swift {
133133
/// Typecheck the given expression.
134134
bool typeCheckExpression(DeclContext *DC, Expr *&parsedExpr);
135135

136-
/// Partially typecheck the specified function body.
137-
bool typeCheckAbstractFunctionBodyNodeAt(AbstractFunctionDecl *AFD,
138-
SourceLoc TargetLoc);
136+
/// Type check a function body element which is at \p TagetLoc .
137+
bool typeCheckAbstractFunctionBodyAtLoc(AbstractFunctionDecl *AFD,
138+
SourceLoc TargetLoc);
139139

140140
/// Typecheck top-level code parsed during code completion.
141141
///

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void typeCheckContextImpl(DeclContext *DC, SourceLoc Loc) {
7979
auto &SM = DC->getASTContext().SourceMgr;
8080
auto bodyRange = AFD->getBodySourceRange();
8181
if (SM.rangeContainsTokenLoc(bodyRange, Loc)) {
82-
swift::typeCheckAbstractFunctionBodyNodeAt(AFD, Loc);
82+
swift::typeCheckAbstractFunctionBodyAtLoc(AFD, Loc);
8383
} else {
8484
assert(bodyRange.isInvalid() && "The body should not be parsed if the "
8585
"completion happens in the signature");
@@ -866,10 +866,10 @@ class ExprContextAnalyzer {
866866
break;
867867
}
868868
default:
869-
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
870-
assert(isSingleExpressionBodyForCodeCompletion(AFD->getBody()));
869+
if (auto *FD = dyn_cast<FuncDecl>(D)) {
870+
assert(isSingleExpressionBodyForCodeCompletion(FD->getBody()));
871871
singleExpressionBody = true;
872-
recordPossibleType(getReturnTypeFromContext(AFD));
872+
recordPossibleType(getReturnTypeFromContext(FD));
873873
break;
874874
}
875875
llvm_unreachable("Unhandled decl kind.");
@@ -1003,8 +1003,8 @@ class ExprContextAnalyzer {
10031003
case DeclKind::PatternBinding:
10041004
return true;
10051005
default:
1006-
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
1007-
if (auto *body = AFD->getBody())
1006+
if (auto *FD = dyn_cast<FuncDecl>(D))
1007+
if (auto *body = FD->getBody())
10081008
return isSingleExpressionBodyForCodeCompletion(body);
10091009
return false;
10101010
}

lib/Sema/TypeCheckStmt.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,9 +1635,8 @@ static Type getFunctionBuilderType(FuncDecl *FD) {
16351635
}
16361636

16371637
bool TypeChecker::typeCheckAbstractFunctionBody(AbstractFunctionDecl *AFD) {
1638-
auto res =
1639-
evaluateOrDefault(AFD->getASTContext().evaluator,
1640-
TypeCheckFunctionBodyRequest{AFD, SourceLoc()}, true);
1638+
auto res = evaluateOrDefault(AFD->getASTContext().evaluator,
1639+
TypeCheckFunctionBodyRequest{AFD}, true);
16411640
TypeChecker::checkFunctionErrorHandling(AFD);
16421641
TypeChecker::computeCaptures(AFD);
16431642
return res;
@@ -1836,10 +1835,41 @@ static void checkClassConstructorBody(ClassDecl *classDecl,
18361835
}
18371836
}
18381837

1838+
bool TypeCheckFunctionBodyAtLocRequest::evaluate(Evaluator &evaluator,
1839+
AbstractFunctionDecl *AFD,
1840+
SourceLoc Loc) const {
1841+
ASTContext &ctx = AFD->getASTContext();
1842+
1843+
BraceStmt *body = AFD->getBody();
1844+
if (!body || AFD->isBodyTypeChecked())
1845+
return false;
1846+
1847+
// Function builder doesn't support partial type checking.
1848+
if (auto *func = dyn_cast<FuncDecl>(AFD)) {
1849+
if (Type builderType = getFunctionBuilderType(func)) {
1850+
auto optBody =
1851+
TypeChecker::applyFunctionBuilderBodyTransform(func, builderType);
1852+
if (!optBody || !*optBody)
1853+
return true;
1854+
// Wire up the function body now.
1855+
AFD->setBody(*optBody, AbstractFunctionDecl::BodyKind::TypeChecked);
1856+
return false;
1857+
}
1858+
}
1859+
1860+
if (ctx.LangOpts.EnableASTScopeLookup)
1861+
ASTScope::expandFunctionBody(AFD);
1862+
1863+
StmtChecker SC(AFD);
1864+
SC.TargetTypeCheckLoc = Loc;
1865+
bool hadError = SC.typeCheckBody(body);
1866+
AFD->setBody(body, AbstractFunctionDecl::BodyKind::TypeChecked);
1867+
return hadError;
1868+
}
1869+
18391870
bool
18401871
TypeCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
1841-
AbstractFunctionDecl *AFD,
1842-
SourceLoc targetTypeCheckLoc) const {
1872+
AbstractFunctionDecl *AFD) const {
18431873
ASTContext &ctx = AFD->getASTContext();
18441874

18451875
Optional<FunctionBodyTimer> timer;
@@ -1896,7 +1926,6 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
18961926
bool hadError = false;
18971927
if (!alreadyTypeChecked) {
18981928
StmtChecker SC(AFD);
1899-
SC.TargetTypeCheckLoc = targetTypeCheckLoc;
19001929
hadError = SC.typeCheckBody(body);
19011930
}
19021931

@@ -1927,7 +1956,7 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
19271956
AFD->setBody(body, AbstractFunctionDecl::BodyKind::TypeChecked);
19281957

19291958
// If nothing went wrong yet, perform extra checking.
1930-
if (!hadError && targetTypeCheckLoc.isInvalid())
1959+
if (!hadError)
19311960
performAbstractFuncDeclDiagnostics(AFD);
19321961

19331962
return hadError;

lib/Sema/TypeChecker.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,12 +540,13 @@ bool swift::typeCheckExpression(DeclContext *DC, Expr *&parsedExpr) {
540540
return !resultTy;
541541
}
542542

543-
bool swift::typeCheckAbstractFunctionBodyNodeAt(AbstractFunctionDecl *AFD,
544-
SourceLoc TargetLoc) {
543+
bool swift::typeCheckAbstractFunctionBodyAtLoc(AbstractFunctionDecl *AFD,
544+
SourceLoc TargetLoc) {
545545
auto &Ctx = AFD->getASTContext();
546546
DiagnosticSuppression suppression(Ctx.Diags);
547547
return !evaluateOrDefault(Ctx.evaluator,
548-
TypeCheckFunctionBodyRequest{AFD, TargetLoc}, true);
548+
TypeCheckFunctionBodyAtLocRequest{AFD, TargetLoc},
549+
true);
549550
}
550551

551552
bool swift::typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD) {

0 commit comments

Comments
 (0)