@@ -1379,6 +1379,73 @@ namespace {
1379
1379
return constructor;
1380
1380
}
1381
1381
1382
+ // / Make a struct declaration into a raw-value-backed struct
1383
+ // /
1384
+ // / \param structDecl the struct to make a raw value for
1385
+ // / \param underlyingType the type of the raw value
1386
+ // / \param synthesizedProtocolAttrs synthesized protocol attributes to add
1387
+ // / \param protocols the protocols to make this struct conform to
1388
+ // / \param setterAccessibility the accessiblity of the raw value's setter
1389
+ // / \param isLet whether the raw value should be a let
1390
+ // / \param makeUnlabeledValueInit whether to also create an unlabeled init
1391
+ // / \param isImplicit whether to mark the rawValue as implicit
1392
+ // /
1393
+ // / This will perform most of the work involved in making a new Swift struct
1394
+ // / be backed by a raw value. This will populated derived protocols and
1395
+ // / synthesized protocols, add the new variable and pattern bindings, and
1396
+ // / create the inits parameterized over a raw value
1397
+ // /
1398
+ template <unsigned N>
1399
+ void makeStructRawValued (
1400
+ StructDecl *structDecl,
1401
+ Type underlyingType,
1402
+ ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs,
1403
+ ProtocolDecl *const (&protocols)[N],
1404
+ Accessibility setterAccessibility = Accessibility::Private,
1405
+ bool isLet = true,
1406
+ bool makeUnlabeledValueInit = false,
1407
+ bool isImplicit = true) {
1408
+ auto &cxt = Impl.SwiftContext ;
1409
+ populateInheritedTypes (structDecl, protocols);
1410
+
1411
+ // Note synthesized protocols
1412
+ for (auto kind : synthesizedProtocolAttrs)
1413
+ structDecl->getAttrs ().add (new (cxt) SynthesizedProtocolAttr (kind));
1414
+
1415
+ // Create a variable to store the underlying value.
1416
+ auto varName = cxt.Id_rawValue ;
1417
+ auto var = new (cxt) VarDecl (
1418
+ /* static*/ false ,
1419
+ /* IsLet*/ isLet, SourceLoc (), varName, underlyingType, structDecl);
1420
+ if (isImplicit)
1421
+ var->setImplicit ();
1422
+ var->setAccessibility (Accessibility::Public);
1423
+ var->setSetterAccessibility (setterAccessibility);
1424
+
1425
+ // Create a pattern binding to describe the variable.
1426
+ Pattern *varPattern = createTypedNamedPattern (var);
1427
+
1428
+ auto patternBinding = PatternBindingDecl::create (
1429
+ cxt, SourceLoc (), StaticSpellingKind::None, SourceLoc (), varPattern,
1430
+ nullptr , structDecl);
1431
+ structDecl->setHasDelayedMembers ();
1432
+
1433
+ // Create constructors to initialize that value from a value of the
1434
+ // underlying type.
1435
+ if (makeUnlabeledValueInit)
1436
+ structDecl->addMember (createValueConstructor (
1437
+ structDecl, var,
1438
+ /* wantCtorParamNames=*/ false ,
1439
+ /* wantBody=*/ !Impl.hasFinishedTypeChecking ()));
1440
+ structDecl->addMember (
1441
+ createValueConstructor (structDecl, var,
1442
+ /* wantCtorParamNames=*/ true ,
1443
+ /* wantBody=*/ !Impl.hasFinishedTypeChecking ()));
1444
+
1445
+ structDecl->addMember (patternBinding);
1446
+ structDecl->addMember (var);
1447
+ }
1448
+
1382
1449
// / \brief Create a constructor that initializes a struct from its members.
1383
1450
ConstructorDecl *createValueConstructor (StructDecl *structDecl,
1384
1451
ArrayRef<VarDecl *> members,
@@ -1625,45 +1692,10 @@ namespace {
1625
1692
Loc, name, Loc, None, nullptr , dc);
1626
1693
structDecl->computeType ();
1627
1694
1628
- // Note that this is a raw option set type.
1629
- structDecl->getAttrs ().add (
1630
- new (Impl.SwiftContext ) SynthesizedProtocolAttr (
1631
- KnownProtocolKind::OptionSet));
1632
-
1633
-
1634
- // Create a field to store the underlying value.
1635
- auto varName = Impl.SwiftContext .Id_rawValue ;
1636
- auto var = new (Impl.SwiftContext ) VarDecl (/* static*/ false ,
1637
- /* IsLet*/ true ,
1638
- SourceLoc (), varName,
1639
- underlyingType,
1640
- structDecl);
1641
- var->setImplicit ();
1642
- var->setAccessibility (Accessibility::Public);
1643
- var->setSetterAccessibility (Accessibility::Private);
1644
-
1645
- // Create a pattern binding to describe the variable.
1646
- Pattern *varPattern = createTypedNamedPattern (var);
1647
-
1648
- auto patternBinding =
1649
- PatternBindingDecl::create (Impl.SwiftContext , SourceLoc (),
1650
- StaticSpellingKind::None, SourceLoc (),
1651
- varPattern, nullptr , structDecl);
1652
-
1653
- // Create the init(rawValue:) constructor.
1654
- auto labeledValueConstructor = createValueConstructor (
1655
- structDecl, var,
1656
- /* wantCtorParamNames=*/ true ,
1657
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1658
-
1659
- // Build an OptionSet conformance for the type.
1660
1695
ProtocolDecl *protocols[]
1661
1696
= {cxt.getProtocol (KnownProtocolKind::OptionSet)};
1662
- populateInheritedTypes (structDecl, protocols);
1663
-
1664
- structDecl->addMember (labeledValueConstructor);
1665
- structDecl->addMember (patternBinding);
1666
- structDecl->addMember (var);
1697
+ makeStructRawValued (structDecl, underlyingType,
1698
+ {KnownProtocolKind::OptionSet}, protocols);
1667
1699
return structDecl;
1668
1700
}
1669
1701
@@ -1714,49 +1746,12 @@ namespace {
1714
1746
ProtocolDecl *protocols[]
1715
1747
= {cxt.getProtocol (KnownProtocolKind::RawRepresentable),
1716
1748
cxt.getProtocol (KnownProtocolKind::Equatable)};
1717
- populateInheritedTypes (structDecl, protocols);
1718
-
1719
- // Note that this is a raw representable type.
1720
- structDecl->getAttrs ().add (
1721
- new (Impl.SwiftContext ) SynthesizedProtocolAttr (
1722
- KnownProtocolKind::RawRepresentable));
1723
-
1724
- // Create a variable to store the underlying value.
1725
- auto varName = Impl.SwiftContext .Id_rawValue ;
1726
- auto var = new (Impl.SwiftContext ) VarDecl (/* static*/ false ,
1727
- /* IsLet*/ false ,
1728
- SourceLoc (), varName,
1729
- underlyingType,
1730
- structDecl);
1731
- var->setAccessibility (Accessibility::Public);
1732
- var->setSetterAccessibility (Accessibility::Public);
1733
-
1734
- // Create a pattern binding to describe the variable.
1735
- Pattern *varPattern = createTypedNamedPattern (var);
1736
-
1737
- auto patternBinding =
1738
- PatternBindingDecl::create (Impl.SwiftContext , SourceLoc (),
1739
- StaticSpellingKind::None, SourceLoc (),
1740
- varPattern, nullptr , structDecl);
1741
-
1742
- // Create a constructor to initialize that value from a value of the
1743
- // underlying type.
1744
- auto valueConstructor =
1745
- createValueConstructor (structDecl, var,
1746
- /* wantCtorParamNames=*/ false ,
1747
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1748
- auto labeledValueConstructor =
1749
- createValueConstructor (structDecl, var,
1750
- /* wantCtorParamNames=*/ true ,
1751
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1752
-
1753
- structDecl->setHasDelayedMembers ();
1754
-
1755
- // Set the members of the struct.
1756
- structDecl->addMember (valueConstructor);
1757
- structDecl->addMember (labeledValueConstructor);
1758
- structDecl->addMember (patternBinding);
1759
- structDecl->addMember (var);
1749
+ makeStructRawValued (structDecl, underlyingType,
1750
+ {KnownProtocolKind::RawRepresentable}, protocols,
1751
+ /* setterAccessibility=*/ Accessibility::Public,
1752
+ /* isLet=*/ false ,
1753
+ /* makeUnlabeledValueInit=*/ true ,
1754
+ /* isImplicit=*/ false );
1760
1755
1761
1756
result = structDecl;
1762
1757
break ;
0 commit comments