@@ -1538,17 +1538,22 @@ synthesizeUnwrappingGetterBody(AbstractFunctionDecl *afd, void *context) {
1538
1538
return {body, /* isTypeChecked*/ true };
1539
1539
}
1540
1540
1541
- // / Synthesizer callback for a subscript setter.
1541
+ // / Synthesizer callback for a subscript setter or a setter for a dereference
1542
+ // / property (`var pointee`).
1542
1543
static std::pair<BraceStmt *, bool >
1543
- synthesizeSubscriptSetterBody (AbstractFunctionDecl *afd, void *context) {
1544
+ synthesizeUnwrappingSetterBody (AbstractFunctionDecl *afd, void *context) {
1544
1545
auto setterDecl = cast<AccessorDecl>(afd);
1545
1546
auto setterImpl = static_cast <FuncDecl *>(context);
1546
1547
1547
1548
ASTContext &ctx = setterDecl->getASTContext ();
1548
1549
1549
1550
auto selfArg = createSelfArg (setterDecl);
1550
1551
DeclRefExpr *valueParamRefExpr = createParamRefExpr (setterDecl, 0 );
1551
- DeclRefExpr *keyParamRefExpr = createParamRefExpr (setterDecl, 1 );
1552
+ // For a subscript this decl will have two parameters, for a pointee property
1553
+ // it will only have one.
1554
+ DeclRefExpr *keyParamRefExpr = setterDecl->getParameters ()->size () == 1
1555
+ ? nullptr
1556
+ : createParamRefExpr (setterDecl, 1 );
1552
1557
1553
1558
Type elementTy = valueParamRefExpr->getDecl ()->getInterfaceType ();
1554
1559
@@ -1644,7 +1649,7 @@ SubscriptDecl *SwiftDeclSynthesizer::makeSubscript(FuncDecl *getter,
1644
1649
setterDecl->setImplicit ();
1645
1650
setterDecl->setIsDynamic (false );
1646
1651
setterDecl->setIsTransparent (true );
1647
- setterDecl->setBodySynthesizer (synthesizeSubscriptSetterBody , setterImpl);
1652
+ setterDecl->setBodySynthesizer (synthesizeUnwrappingSetterBody , setterImpl);
1648
1653
1649
1654
if (setterImpl->isMutating ()) {
1650
1655
setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
@@ -1663,28 +1668,34 @@ SubscriptDecl *SwiftDeclSynthesizer::makeSubscript(FuncDecl *getter,
1663
1668
1664
1669
// MARK: C++ dereference operator
1665
1670
1666
- VarDecl *SwiftDeclSynthesizer::makeDereferencedPointeeProperty (
1667
- FuncDecl *dereferenceFunc) {
1671
+ VarDecl *
1672
+ SwiftDeclSynthesizer::makeDereferencedPointeeProperty (FuncDecl *getter,
1673
+ FuncDecl *setter) {
1674
+ assert ((getter || setter) &&
1675
+ " getter or setter required to generate a pointee property" );
1676
+
1668
1677
auto &ctx = ImporterImpl.SwiftContext ;
1669
- auto dc = dereferenceFunc->getDeclContext ();
1678
+ FuncDecl *getterImpl = getter ? getter : setter;
1679
+ FuncDecl *setterImpl = setter;
1680
+ auto dc = getterImpl->getDeclContext ();
1670
1681
1671
1682
// Get the return type wrapped in `Unsafe(Mutable)Pointer<T>`.
1672
- const auto rawElementTy = dereferenceFunc ->getResultInterfaceType ();
1683
+ const auto rawElementTy = getterImpl ->getResultInterfaceType ();
1673
1684
// Unwrap `T`. Use rawElementTy for return by value.
1674
1685
const auto elementTy = rawElementTy->getAnyPointerElementType ()
1675
1686
? rawElementTy->getAnyPointerElementType ()
1676
1687
: rawElementTy;
1677
1688
1678
1689
auto result = new (ctx)
1679
1690
VarDecl (/* isStatic*/ false , VarDecl::Introducer::Var,
1680
- dereferenceFunc ->getStartLoc (), ctx.getIdentifier (" pointee" ), dc);
1691
+ getterImpl ->getStartLoc (), ctx.getIdentifier (" pointee" ), dc);
1681
1692
result->setInterfaceType (elementTy);
1682
1693
result->setAccess (AccessLevel::Public);
1683
1694
result->setImplInfo (StorageImplInfo::getImmutableComputed ());
1684
1695
1685
1696
AccessorDecl *getterDecl = AccessorDecl::create (
1686
- ctx, dereferenceFunc ->getLoc (), dereferenceFunc ->getLoc (),
1687
- AccessorKind::Get, result, SourceLoc (), StaticSpellingKind::None,
1697
+ ctx, getterImpl ->getLoc (), getterImpl ->getLoc (), AccessorKind::Get ,
1698
+ result, SourceLoc (), StaticSpellingKind::None,
1688
1699
/* async*/ false , SourceLoc (),
1689
1700
/* throws*/ false , SourceLoc (), ParameterList::createEmpty (ctx), elementTy,
1690
1701
dc);
@@ -1693,14 +1704,43 @@ VarDecl *SwiftDeclSynthesizer::makeDereferencedPointeeProperty(
1693
1704
getterDecl->setIsDynamic (false );
1694
1705
getterDecl->setIsTransparent (true );
1695
1706
getterDecl->setBodySynthesizer (synthesizeUnwrappingGetterBody,
1696
- dereferenceFunc );
1707
+ getterImpl );
1697
1708
1698
- if (dereferenceFunc ->isMutating ()) {
1709
+ if (getterImpl ->isMutating ()) {
1699
1710
getterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
1700
1711
result->setIsGetterMutating (true );
1701
1712
}
1702
1713
1703
- ImporterImpl.makeComputed (result, getterDecl, /* setter*/ nullptr );
1714
+ AccessorDecl *setterDecl = nullptr ;
1715
+ if (setterImpl) {
1716
+ auto paramVarDecl =
1717
+ new (ctx) ParamDecl (SourceLoc (), SourceLoc (), Identifier (), SourceLoc (),
1718
+ ctx.getIdentifier (" newValue" ), dc);
1719
+ paramVarDecl->setSpecifier (ParamSpecifier::Default);
1720
+ paramVarDecl->setInterfaceType (elementTy);
1721
+
1722
+ auto setterParamList =
1723
+ ParameterList::create (ctx, {paramVarDecl});
1724
+
1725
+ setterDecl = AccessorDecl::create (
1726
+ ctx, setterImpl->getLoc (), setterImpl->getLoc (), AccessorKind::Set,
1727
+ result, SourceLoc (), StaticSpellingKind::None,
1728
+ /* async*/ false , SourceLoc (),
1729
+ /* throws*/ false , SourceLoc (), setterParamList,
1730
+ TupleType::getEmpty (ctx), dc);
1731
+ setterDecl->setAccess (AccessLevel::Public);
1732
+ setterDecl->setImplicit ();
1733
+ setterDecl->setIsDynamic (false );
1734
+ setterDecl->setIsTransparent (true );
1735
+ setterDecl->setBodySynthesizer (synthesizeUnwrappingSetterBody, setterImpl);
1736
+
1737
+ if (setterImpl->isMutating ()) {
1738
+ setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
1739
+ result->setIsSetterMutating (true );
1740
+ }
1741
+ }
1742
+
1743
+ ImporterImpl.makeComputed (result, getterDecl, setterDecl);
1704
1744
return result;
1705
1745
}
1706
1746
0 commit comments