Skip to content

Commit 27b12bf

Browse files
authored
Merge pull request #23978 from AnthonyLatsis/expand-closure-check-braces
SourceKit: Account for existing braces when expanding closure placeholders
2 parents 81ce653 + 7344fdb commit 27b12bf

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
@@ -93,3 +93,13 @@ if true {
9393

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

tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,16 +1566,29 @@ class PlaceholderExpansionScanner {
15661566
}
15671567

15681568
bool shouldUseTrailingClosureInTuple(TupleExpr *TE,
1569-
SourceLoc PlaceHolderStartLoc) {
1570-
if (!TE->getElements().empty()) {
1571-
for (unsigned I = 0, N = TE->getNumElements(); I < N; ++ I) {
1572-
bool IsLast = I == N - 1;
1573-
Expr *E = TE->getElement(I);
1574-
if (IsLast) {
1575-
return E->getStartLoc() == PlaceHolderStartLoc;
1576-
} else if (containClosure(E)) {
1577-
return false;
1569+
SourceLoc PlaceHolderStartLoc,
1570+
bool &isWrappedWithBraces) {
1571+
if (TE->getElements().empty())
1572+
return false;
1573+
1574+
for (unsigned I = 0, N = TE->getNumElements(); I < N; ++ I) {
1575+
bool IsLast = I == N - 1;
1576+
Expr *E = TE->getElement(I);
1577+
1578+
// Placeholders wrapped in braces {<#T##() -> Int#>} can also
1579+
// be valid for trailing syntax.
1580+
if (auto CE = dyn_cast<ClosureExpr>(E)) {
1581+
if (CE->hasSingleExpressionBody() &&
1582+
CE->getSingleExpressionBody()->getStartLoc()
1583+
== PlaceHolderStartLoc) {
1584+
// We found the placeholder.
1585+
isWrappedWithBraces = true;
1586+
return IsLast;
15781587
}
1588+
} else if (IsLast) {
1589+
return E->getStartLoc() == PlaceHolderStartLoc;
1590+
} else if (containClosure(E)) {
1591+
return false;
15791592
}
15801593
}
15811594
return false;
@@ -1590,6 +1603,7 @@ class PlaceholderExpansionScanner {
15901603
bool scan(SourceFile &SF, unsigned BufID, unsigned Offset,
15911604
unsigned Length, std::function<void(Expr *Args,
15921605
bool UseTrailingClosure,
1606+
bool isWrappedWithBraces,
15931607
ArrayRef<Param>,
15941608
CharSourceRange)> Callback,
15951609
std::function<bool(EditorPlaceholderExpr*)> NonClosureCallback) {
@@ -1606,18 +1620,21 @@ class PlaceholderExpansionScanner {
16061620
// and if the call parens can be removed in that case.
16071621
// We'll first find the enclosing CallExpr, and then do further analysis.
16081622
bool UseTrailingClosure = false;
1623+
bool isWrappedWithBraces = false;
16091624
auto ECE = enclosingCallExprArg(SF, PlaceholderStartLoc);
16101625
Expr *Args = ECE.first;
16111626
if (Args && ECE.second) {
16121627
if (isa<ParenExpr>(Args)) {
16131628
UseTrailingClosure = true;
16141629
} else if (auto *TE = dyn_cast<TupleExpr>(Args)) {
1615-
UseTrailingClosure = shouldUseTrailingClosureInTuple(TE,
1616-
PlaceholderStartLoc);
1630+
UseTrailingClosure = shouldUseTrailingClosureInTuple(
1631+
TE, PlaceholderStartLoc,
1632+
isWrappedWithBraces);
16171633
}
16181634
}
16191635

1620-
Callback(Args, UseTrailingClosure, TargetClosureInfo.Params,
1636+
Callback(Args, UseTrailingClosure, isWrappedWithBraces,
1637+
TargetClosureInfo.Params,
16211638
TargetClosureInfo.ReturnTypeRange);
16221639
return true;
16231640
}
@@ -1922,7 +1939,7 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length,
19221939

19231940
Scanner.scan(SF, BufID, Offset, Length,
19241941
[&](Expr *Args,
1925-
bool UseTrailingClosure,
1942+
bool UseTrailingClosure, bool isWrappedWithBraces,
19261943
ArrayRef<PlaceholderExpansionScanner::Param> ClosureParams,
19271944
CharSourceRange ClosureReturnTypeRange) {
19281945

@@ -1966,8 +1983,10 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length,
19661983
unsigned End = SM.getLocOffsetInBuffer(Args->getEndLoc(), BufID);
19671984
EffectiveLength = (End + 1) - EffectiveOffset;
19681985
}
1969-
1970-
OS << "{ ";
1986+
// Trailing closure syntax handling will replace braces anyway.
1987+
bool printBraces = !isWrappedWithBraces || UseTrailingClosure;
1988+
if (printBraces)
1989+
OS << "{ ";
19711990

19721991
bool ReturningVoid = isReturningVoid(SM, ClosureReturnTypeRange);
19731992

@@ -2009,7 +2028,8 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length,
20092028
if (HasSignature)
20102029
OS << "in";
20112030
OS << "\n" << getCodePlaceholder() << "\n";
2012-
OS << "}";
2031+
if (printBraces)
2032+
OS << "}";
20132033
}
20142034
Consumer.handleSourceText(ExpansionStr);
20152035
Consumer.recordAffectedRange(EffectiveOffset, EffectiveLength);

0 commit comments

Comments
 (0)