Skip to content

Commit 7344fdb

Browse files
committed
SourceKit: Account for existing braces when expanding closure placeholders
1 parent bf909ca commit 7344fdb

File tree

2 files changed

+46
-16
lines changed

2 files changed

+46
-16
lines changed

test/SourceKit/CodeExpand/code-expand.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,13 @@ if true {
9191

9292
foo(.foo(<#T##block: () -> Void##() -> Void#>))
9393
// CHECK: foo(.foo({
94+
95+
braced1(x: {<#T##() -> Void#>})
96+
// CHECK: braced1 {
97+
// CHECK-NEXT: <#code#>
98+
// CHECK-NEXT: }
99+
100+
braced2(x: {<#T##() -> Void#>}, y: Int)
101+
// CHECK: braced2(x: {
102+
// CHECK-NEXT: <#code#>
103+
// CHECK-NEXT: }, y: Int)

tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,16 +1563,29 @@ class PlaceholderExpansionScanner {
15631563
}
15641564

15651565
bool shouldUseTrailingClosureInTuple(TupleExpr *TE,
1566-
SourceLoc PlaceHolderStartLoc) {
1567-
if (!TE->getElements().empty()) {
1568-
for (unsigned I = 0, N = TE->getNumElements(); I < N; ++ I) {
1569-
bool IsLast = I == N - 1;
1570-
Expr *E = TE->getElement(I);
1571-
if (IsLast) {
1572-
return E->getStartLoc() == PlaceHolderStartLoc;
1573-
} else if (containClosure(E)) {
1574-
return false;
1566+
SourceLoc PlaceHolderStartLoc,
1567+
bool &isWrappedWithBraces) {
1568+
if (TE->getElements().empty())
1569+
return false;
1570+
1571+
for (unsigned I = 0, N = TE->getNumElements(); I < N; ++ I) {
1572+
bool IsLast = I == N - 1;
1573+
Expr *E = TE->getElement(I);
1574+
1575+
// Placeholders wrapped in braces {<#T##() -> Int#>} can also
1576+
// be valid for trailing syntax.
1577+
if (auto CE = dyn_cast<ClosureExpr>(E)) {
1578+
if (CE->hasSingleExpressionBody() &&
1579+
CE->getSingleExpressionBody()->getStartLoc()
1580+
== PlaceHolderStartLoc) {
1581+
// We found the placeholder.
1582+
isWrappedWithBraces = true;
1583+
return IsLast;
15751584
}
1585+
} else if (IsLast) {
1586+
return E->getStartLoc() == PlaceHolderStartLoc;
1587+
} else if (containClosure(E)) {
1588+
return false;
15761589
}
15771590
}
15781591
return false;
@@ -1587,6 +1600,7 @@ class PlaceholderExpansionScanner {
15871600
bool scan(SourceFile &SF, unsigned BufID, unsigned Offset,
15881601
unsigned Length, std::function<void(Expr *Args,
15891602
bool UseTrailingClosure,
1603+
bool isWrappedWithBraces,
15901604
ArrayRef<Param>,
15911605
CharSourceRange)> Callback,
15921606
std::function<bool(EditorPlaceholderExpr*)> NonClosureCallback) {
@@ -1603,18 +1617,21 @@ class PlaceholderExpansionScanner {
16031617
// and if the call parens can be removed in that case.
16041618
// We'll first find the enclosing CallExpr, and then do further analysis.
16051619
bool UseTrailingClosure = false;
1620+
bool isWrappedWithBraces = false;
16061621
auto ECE = enclosingCallExprArg(SF, PlaceholderStartLoc);
16071622
Expr *Args = ECE.first;
16081623
if (Args && ECE.second) {
16091624
if (isa<ParenExpr>(Args)) {
16101625
UseTrailingClosure = true;
16111626
} else if (auto *TE = dyn_cast<TupleExpr>(Args)) {
1612-
UseTrailingClosure = shouldUseTrailingClosureInTuple(TE,
1613-
PlaceholderStartLoc);
1627+
UseTrailingClosure = shouldUseTrailingClosureInTuple(
1628+
TE, PlaceholderStartLoc,
1629+
isWrappedWithBraces);
16141630
}
16151631
}
16161632

1617-
Callback(Args, UseTrailingClosure, TargetClosureInfo.Params,
1633+
Callback(Args, UseTrailingClosure, isWrappedWithBraces,
1634+
TargetClosureInfo.Params,
16181635
TargetClosureInfo.ReturnTypeRange);
16191636
return true;
16201637
}
@@ -1919,7 +1936,7 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length,
19191936

19201937
Scanner.scan(SF, BufID, Offset, Length,
19211938
[&](Expr *Args,
1922-
bool UseTrailingClosure,
1939+
bool UseTrailingClosure, bool isWrappedWithBraces,
19231940
ArrayRef<PlaceholderExpansionScanner::Param> ClosureParams,
19241941
CharSourceRange ClosureReturnTypeRange) {
19251942

@@ -1963,8 +1980,10 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length,
19631980
unsigned End = SM.getLocOffsetInBuffer(Args->getEndLoc(), BufID);
19641981
EffectiveLength = (End + 1) - EffectiveOffset;
19651982
}
1966-
1967-
OS << "{ ";
1983+
// Trailing closure syntax handling will replace braces anyway.
1984+
bool printBraces = !isWrappedWithBraces || UseTrailingClosure;
1985+
if (printBraces)
1986+
OS << "{ ";
19681987

19691988
bool ReturningVoid = isReturningVoid(SM, ClosureReturnTypeRange);
19701989

@@ -2006,7 +2025,8 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length,
20062025
if (HasSignature)
20072026
OS << "in";
20082027
OS << "\n" << getCodePlaceholder() << "\n";
2009-
OS << "}";
2028+
if (printBraces)
2029+
OS << "}";
20102030
}
20112031
Consumer.handleSourceText(ExpansionStr);
20122032
Consumer.recordAffectedRange(EffectiveOffset, EffectiveLength);

0 commit comments

Comments
 (0)