@@ -1351,6 +1351,7 @@ class SwiftEditorSyntaxWalker: public ide::SyntaxModelWalker {
1351
1351
};
1352
1352
1353
1353
class PlaceholderExpansionScanner {
1354
+
1354
1355
public:
1355
1356
struct Param {
1356
1357
CharSourceRange NameRange;
@@ -1360,9 +1361,14 @@ class PlaceholderExpansionScanner {
1360
1361
};
1361
1362
1362
1363
private:
1364
+
1365
+ struct ClosureInfo {
1366
+ std::vector<Param> Params;
1367
+ CharSourceRange ReturnTypeRange;
1368
+ };
1369
+
1363
1370
SourceManager &SM;
1364
- std::vector<Param> Params;
1365
- CharSourceRange ReturnTypeRange;
1371
+ ClosureInfo TargetClosureInfo;
1366
1372
EditorPlaceholderExpr *PHE = nullptr ;
1367
1373
1368
1374
class PlaceholderFinder : public ASTWalker {
@@ -1384,61 +1390,80 @@ class PlaceholderExpansionScanner {
1384
1390
}
1385
1391
};
1386
1392
1387
- bool scanClosureType (SourceFile &SF, SourceLoc PlaceholderLoc) {
1388
- Params.clear ();
1389
- ReturnTypeRange = CharSourceRange ();
1390
- PlaceholderFinder Finder (PlaceholderLoc, PHE);
1391
- SF.walk (Finder);
1392
- if (!PHE || !PHE->getTypeForExpansion ())
1393
- return false ;
1394
-
1395
- class ClosureTypeWalker : public ASTWalker {
1396
- public:
1397
- PlaceholderExpansionScanner &S;
1398
- bool FoundFunctionTypeRepr = false ;
1399
- explicit ClosureTypeWalker (PlaceholderExpansionScanner &S)
1400
- :S(S) { }
1401
-
1402
- bool walkToTypeReprPre (TypeRepr *T) override {
1403
- if (auto *FTR = dyn_cast<FunctionTypeRepr>(T)) {
1404
- FoundFunctionTypeRepr = true ;
1405
- if (auto *TTR = dyn_cast_or_null<TupleTypeRepr>(FTR->getArgsTypeRepr ())) {
1406
- for (auto *ArgTR : TTR->getElements ()) {
1407
- CharSourceRange NR;
1408
- CharSourceRange TR;
1409
- auto *NTR = dyn_cast<NamedTypeRepr>(ArgTR);
1410
- if (NTR && NTR->hasName ()) {
1411
- NR = CharSourceRange (NTR->getNameLoc (),
1412
- NTR->getName ().getLength ());
1413
- ArgTR = NTR->getTypeRepr ();
1414
- }
1415
- SourceLoc SRE = Lexer::getLocForEndOfToken (S.SM ,
1416
- ArgTR->getEndLoc ());
1417
- TR = CharSourceRange (S.SM , ArgTR->getStartLoc (), SRE);
1418
- S.Params .emplace_back (NR, TR);
1419
- }
1420
- } else if (FTR->getArgsTypeRepr ()) {
1393
+ class ClosureTypeWalker : public ASTWalker {
1394
+ SourceManager &SM;
1395
+ ClosureInfo &Info;
1396
+ public:
1397
+ bool FoundFunctionTypeRepr = false ;
1398
+ explicit ClosureTypeWalker (SourceManager &SM, ClosureInfo &Info) : SM(SM),
1399
+ Info(Info) { }
1400
+
1401
+ bool walkToTypeReprPre (TypeRepr *T) override {
1402
+ if (auto *FTR = dyn_cast<FunctionTypeRepr>(T)) {
1403
+ FoundFunctionTypeRepr = true ;
1404
+ if (auto *TTR = dyn_cast_or_null<TupleTypeRepr>(FTR->getArgsTypeRepr ())) {
1405
+ for (auto *ArgTR : TTR->getElements ()) {
1406
+ CharSourceRange NR;
1421
1407
CharSourceRange TR;
1422
- TR = CharSourceRange (S.SM , FTR->getArgsTypeRepr ()->getStartLoc (),
1423
- Lexer::getLocForEndOfToken (S.SM ,
1424
- FTR->getArgsTypeRepr ()->getEndLoc ()));
1425
- S.Params .emplace_back (CharSourceRange (), TR);
1426
- }
1427
- if (auto *RTR = FTR->getResultTypeRepr ()) {
1428
- SourceLoc SRE = Lexer::getLocForEndOfToken (S.SM , RTR->getEndLoc ());
1429
- S.ReturnTypeRange = CharSourceRange (S.SM , RTR->getStartLoc (), SRE);
1408
+ auto *NTR = dyn_cast<NamedTypeRepr>(ArgTR);
1409
+ if (NTR && NTR->hasName ()) {
1410
+ NR = CharSourceRange (NTR->getNameLoc (),
1411
+ NTR->getName ().getLength ());
1412
+ ArgTR = NTR->getTypeRepr ();
1413
+ }
1414
+ SourceLoc SRE = Lexer::getLocForEndOfToken (SM,
1415
+ ArgTR->getEndLoc ());
1416
+ TR = CharSourceRange (SM, ArgTR->getStartLoc (), SRE);
1417
+ Info.Params .emplace_back (NR, TR);
1430
1418
}
1419
+ } else if (FTR->getArgsTypeRepr ()) {
1420
+ CharSourceRange TR;
1421
+ TR = CharSourceRange (SM, FTR->getArgsTypeRepr ()->getStartLoc (),
1422
+ Lexer::getLocForEndOfToken (SM,
1423
+ FTR->getArgsTypeRepr ()->getEndLoc ()));
1424
+ Info.Params .emplace_back (CharSourceRange (), TR);
1425
+ }
1426
+ if (auto *RTR = FTR->getResultTypeRepr ()) {
1427
+ SourceLoc SRE = Lexer::getLocForEndOfToken (SM, RTR->getEndLoc ());
1428
+ Info.ReturnTypeRange = CharSourceRange (SM, RTR->getStartLoc (), SRE);
1431
1429
}
1432
- return !FoundFunctionTypeRepr;
1433
1430
}
1431
+ return !FoundFunctionTypeRepr;
1432
+ }
1434
1433
1435
- bool walkToTypeReprPost (TypeRepr *T) override {
1436
- // If we just visited the FunctionTypeRepr, end traversal.
1437
- return !FoundFunctionTypeRepr;
1438
- }
1434
+ bool walkToTypeReprPost (TypeRepr *T) override {
1435
+ // If we just visited the FunctionTypeRepr, end traversal.
1436
+ return !FoundFunctionTypeRepr;
1437
+ }
1439
1438
1440
- } PW (* this ) ;
1439
+ } ;
1441
1440
1441
+ bool containClosure (Expr *E) {
1442
+ if (E->getStartLoc ().isInvalid ())
1443
+ return false ;
1444
+ EditorPlaceholderExpr *Found;
1445
+ ClosureInfo Info;
1446
+ ClosureTypeWalker ClosureWalker (SM, Info);
1447
+ PlaceholderFinder Finder (E->getStartLoc (), Found);
1448
+ E->walk (Finder);
1449
+ if (Found) {
1450
+ if (auto TR = Found->getTypeLoc ().getTypeRepr ()) {
1451
+ TR->walk (ClosureWalker);
1452
+ return ClosureWalker.FoundFunctionTypeRepr ;
1453
+ }
1454
+ }
1455
+ E->walk (ClosureWalker);
1456
+ return ClosureWalker.FoundFunctionTypeRepr ;
1457
+ }
1458
+
1459
+ bool scanClosureType (SourceFile &SF, SourceLoc PlaceholderLoc) {
1460
+ TargetClosureInfo.Params .clear ();
1461
+ TargetClosureInfo.ReturnTypeRange = CharSourceRange ();
1462
+ PlaceholderFinder Finder (PlaceholderLoc, PHE);
1463
+ SF.walk (Finder);
1464
+ if (!PHE || !PHE->getTypeForExpansion ())
1465
+ return false ;
1466
+ ClosureTypeWalker PW (SM, TargetClosureInfo);
1442
1467
PHE->getTypeForExpansion ()->walk (PW);
1443
1468
return PW.FoundFunctionTypeRepr ;
1444
1469
}
@@ -1512,6 +1537,22 @@ class PlaceholderExpansionScanner {
1512
1537
return std::make_pair (CE, true );
1513
1538
}
1514
1539
1540
+ bool shouldUseTrailingClosureInTuple (TupleExpr *TE,
1541
+ SourceLoc PlaceHolderStartLoc) {
1542
+ if (!TE->getElements ().empty ()) {
1543
+ for (unsigned I = 0 , N = TE->getNumElements (); I < N; ++ I) {
1544
+ bool IsLast = I == N - 1 ;
1545
+ Expr *E = TE->getElement (I);
1546
+ if (IsLast) {
1547
+ return E->getStartLoc () == PlaceHolderStartLoc;
1548
+ } else if (containClosure (E)) {
1549
+ return false ;
1550
+ }
1551
+ }
1552
+ }
1553
+ return false ;
1554
+ }
1555
+
1515
1556
public:
1516
1557
explicit PlaceholderExpansionScanner (SourceManager &SM) : SM(SM) { }
1517
1558
@@ -1543,13 +1584,13 @@ class PlaceholderExpansionScanner {
1543
1584
if (isa<ParenExpr>(Args)) {
1544
1585
UseTrailingClosure = true ;
1545
1586
} else if (auto *TE = dyn_cast<TupleExpr>(Args)) {
1546
- if (!TE->getElements ().empty ())
1547
- UseTrailingClosure =
1548
- TE->getElements ().back ()->getStartLoc () == PlaceholderStartLoc;
1587
+ UseTrailingClosure = shouldUseTrailingClosureInTuple (TE,
1588
+ PlaceholderStartLoc);
1549
1589
}
1550
1590
}
1551
1591
1552
- Callback (Args, UseTrailingClosure, Params, ReturnTypeRange);
1592
+ Callback (Args, UseTrailingClosure, TargetClosureInfo.Params ,
1593
+ TargetClosureInfo.ReturnTypeRange );
1553
1594
return true ;
1554
1595
}
1555
1596
0 commit comments