|
22 | 22 | #include "swift/AST/Decl.h" |
23 | 23 | #include "swift/AST/Expr.h" |
24 | 24 | #include "swift/AST/GenericSignature.h" |
| 25 | +#include "swift/AST/Initializer.h" |
25 | 26 | #include "swift/AST/ParameterList.h" |
26 | 27 | #include "swift/AST/Pattern.h" |
27 | 28 | #include "swift/AST/ProtocolConformance.h" |
@@ -1348,6 +1349,9 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const { |
1348 | 1349 | srcFT->getResult()) |
1349 | 1350 | .highlight(anchor->getSourceRange()) |
1350 | 1351 | .fixItInsertAfter(anchor->getEndLoc(), "()"); |
| 1352 | + |
| 1353 | + tryComputedPropertyFixIts(anchor); |
| 1354 | + |
1351 | 1355 | return true; |
1352 | 1356 | } |
1353 | 1357 |
|
@@ -1378,6 +1382,53 @@ bool ContextualFailure::trySequenceSubsequenceFixIts(InFlightDiagnostic &diag, |
1378 | 1382 | return false; |
1379 | 1383 | } |
1380 | 1384 |
|
| 1385 | +void ContextualFailure::tryComputedPropertyFixIts(Expr *expr) const { |
| 1386 | + if (!isa<ClosureExpr>(expr)) |
| 1387 | + return; |
| 1388 | + |
| 1389 | + // It is possible that we're looking at a stored property being |
| 1390 | + // initialized with a closure. Something like: |
| 1391 | + // |
| 1392 | + // var foo: Int = { return 0 } |
| 1393 | + // |
| 1394 | + // Let's offer another fix-it to remove the '=' to turn the stored |
| 1395 | + // property into a computed property. If the variable is immutable, then |
| 1396 | + // replace the 'let' with a 'var'. |
| 1397 | + |
| 1398 | + PatternBindingDecl *PBD = nullptr; |
| 1399 | + |
| 1400 | + if (auto TLCD = dyn_cast<TopLevelCodeDecl>(getDC())) { |
| 1401 | + if (TLCD->getBody()->isImplicit()) { |
| 1402 | + if (auto decl = TLCD->getBody()->getElement(0).dyn_cast<Decl *>()) { |
| 1403 | + if (auto binding = dyn_cast<PatternBindingDecl>(decl)) { |
| 1404 | + PBD = binding; |
| 1405 | + } |
| 1406 | + } |
| 1407 | + } |
| 1408 | + } else if (auto PBI = dyn_cast<PatternBindingInitializer>(getDC())) { |
| 1409 | + PBD = PBI->getBinding(); |
| 1410 | + } |
| 1411 | + |
| 1412 | + if (PBD) { |
| 1413 | + if (auto VD = PBD->getSingleVar()) { |
| 1414 | + auto entry = PBD->getPatternEntryForVarDecl(VD); |
| 1415 | + |
| 1416 | + if (!VD->isStatic() && |
| 1417 | + !VD->getAttrs().getAttribute<DynamicReplacementAttr>() && |
| 1418 | + entry.getInit() && isa<ClosureExpr>(entry.getInit())) { |
| 1419 | + auto diag = emitDiagnostic(expr->getLoc(), |
| 1420 | + diag::extension_stored_property_fixit, |
| 1421 | + VD->getName()); |
| 1422 | + diag.fixItRemove(entry.getEqualLoc()); |
| 1423 | + |
| 1424 | + if (VD->isLet()) { |
| 1425 | + diag.fixItReplace(PBD->getStartLoc(), getTokenText(tok::kw_var)); |
| 1426 | + } |
| 1427 | + } |
| 1428 | + } |
| 1429 | + } |
| 1430 | +} |
| 1431 | + |
1381 | 1432 | bool AutoClosureForwardingFailure::diagnoseAsError() { |
1382 | 1433 | auto path = getLocator()->getPath(); |
1383 | 1434 | assert(!path.empty()); |
|
0 commit comments