Skip to content

Commit 9e57fbf

Browse files
authored
Merge pull request #32952 from rintaro/5.3-ide-completion-rdar65692922
[5.3][CodeCompletion] Fast completion inside function builder function
2 parents ee71704 + 4e8c92e commit 9e57fbf

File tree

5 files changed

+73
-8
lines changed

5 files changed

+73
-8
lines changed

include/swift/AST/Stmt.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,13 @@ class PoundAssertStmt : public Stmt {
13401340
}
13411341
};
13421342

1343+
inline void simple_display(llvm::raw_ostream &out, Stmt *S) {
1344+
if (S)
1345+
out << Stmt::getKindName(S->getKind());
1346+
else
1347+
out << "(null)";
1348+
};
1349+
13431350
} // end namespace swift
13441351

13451352
#endif // SWIFT_AST_STMT_H

include/swift/AST/TypeCheckRequests.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,8 @@ enum class FunctionBuilderBodyPreCheck : uint8_t {
18211821

18221822
class PreCheckFunctionBuilderRequest
18231823
: public SimpleRequest<PreCheckFunctionBuilderRequest,
1824-
FunctionBuilderBodyPreCheck(AnyFunctionRef),
1824+
FunctionBuilderBodyPreCheck(AnyFunctionRef,
1825+
BraceStmt *),
18251826
RequestFlags::Cached> {
18261827
public:
18271828
using SimpleRequest::SimpleRequest;
@@ -1830,8 +1831,8 @@ class PreCheckFunctionBuilderRequest
18301831
friend SimpleRequest;
18311832

18321833
// Evaluation.
1833-
FunctionBuilderBodyPreCheck
1834-
evaluate(Evaluator &evaluator, AnyFunctionRef fn) const;
1834+
FunctionBuilderBodyPreCheck evaluate(Evaluator &evaluator, AnyFunctionRef fn,
1835+
BraceStmt *body) const;
18351836

18361837
public:
18371838
// Separate caching.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ SWIFT_REQUEST(TypeChecker, HasUserDefinedDesignatedInitRequest,
214214
SWIFT_REQUEST(TypeChecker, HasMemberwiseInitRequest,
215215
bool(StructDecl *), Cached, NoLocationInfo)
216216
SWIFT_REQUEST(TypeChecker, PreCheckFunctionBuilderRequest,
217-
FunctionBuilderClosurePreCheck(AnyFunctionRef),
217+
FunctionBuilderClosurePreCheck(AnyFunctionRef, BraceStmt *),
218218
Cached, NoLocationInfo)
219219
SWIFT_REQUEST(TypeChecker, ResolveImplicitMemberRequest,
220220
evaluator::SideEffect(NominalTypeDecl *, ImplicitMemberAction),

lib/Sema/BuilderTransform.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ Optional<BraceStmt *> TypeChecker::applyFunctionBuilderBodyTransform(
12921292
// If we encountered an error or there was an explicit result type,
12931293
// bail out and report that to the caller.
12941294
auto &ctx = func->getASTContext();
1295-
auto request = PreCheckFunctionBuilderRequest{func};
1295+
auto request = PreCheckFunctionBuilderRequest{func, func->getBody()};
12961296
switch (evaluateOrDefault(
12971297
ctx.evaluator, request, FunctionBuilderBodyPreCheck::Error)) {
12981298
case FunctionBuilderBodyPreCheck::Okay:
@@ -1442,7 +1442,7 @@ ConstraintSystem::matchFunctionBuilder(
14421442

14431443
// Pre-check the body: pre-check any expressions in it and look
14441444
// for return statements.
1445-
auto request = PreCheckFunctionBuilderRequest{fn};
1445+
auto request = PreCheckFunctionBuilderRequest{fn, fn.getBody()};
14461446
switch (evaluateOrDefault(getASTContext().evaluator, request,
14471447
FunctionBuilderBodyPreCheck::Error)) {
14481448
case FunctionBuilderBodyPreCheck::Okay:
@@ -1605,8 +1605,14 @@ class PreCheckFunctionBuilderApplication : public ASTWalker {
16051605
}
16061606

16071607
FunctionBuilderBodyPreCheck
1608-
PreCheckFunctionBuilderRequest::evaluate(Evaluator &eval,
1609-
AnyFunctionRef fn) const {
1608+
PreCheckFunctionBuilderRequest::evaluate(Evaluator &eval, AnyFunctionRef fn,
1609+
BraceStmt *body) const {
1610+
// NOTE: 'body' is passed only for the request evaluater caching key.
1611+
// Since source tooling (e.g. code completion) might replace the body,
1612+
// the function alone is not sufficient for the key.
1613+
assert(fn.getBody() == body &&
1614+
"body must be the current body of the function");
1615+
16101616
return PreCheckFunctionBuilderApplication(fn, false).run();
16111617
}
16121618

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
protocol Entity {}
2+
struct Empty: Entity {
3+
var value: Void = ()
4+
}
5+
6+
@_functionBuilder
7+
struct Builder {
8+
static func buildBlock() -> { Empty() }
9+
static func buildBlock<T: Entity>(_ t: T) -> T { t }
10+
}
11+
12+
struct MyValue {
13+
var id: Int
14+
var title: String
15+
}
16+
17+
func build(_ arg: (MyValue) -> String) -> Empty { Empty() }
18+
19+
struct MyStruct {
20+
@Builder var body: some Entity {
21+
build { value in
22+
value./*HERE * 2*/
23+
} /*HERE*/
24+
}
25+
}
26+
27+
// RUN: %sourcekitd-test \
28+
// RUN: -req=complete -pos=22:13 %s -- %s == \
29+
// RUN: -req=complete -pos=22:13 %s -- %s == \
30+
// RUN: -req=complete -pos=23:7 %s -- %s \
31+
// RUN: | tee %t.result | %FileCheck %s
32+
33+
// CHECK-LABEL: key.results: [
34+
// CHECK-DAG: key.description: "id"
35+
// CHECK-DAG: key.description: "title"
36+
// CHECK-DAG: key.description: "self"
37+
// CHECK: ]
38+
// CHECK-NOT: key.reusingastcontext: 1
39+
40+
// CHECK-LABEL: key.results: [
41+
// CHECK-DAG: key.description: "id"
42+
// CHECK-DAG: key.description: "title"
43+
// CHECK-DAG: key.description: "self"
44+
// CHECK: ]
45+
// CHECK: key.reusingastcontext: 1
46+
47+
// CHECK-LABEL: key.results: [
48+
// CHECK-DAG: key.description: "value"
49+
// CHECK: ]
50+
// CHECK: key.reusingastcontext: 1
51+

0 commit comments

Comments
 (0)