@@ -970,6 +970,10 @@ class PrintAST : public ASTVisitor<PrintAST> {
970970 ArrayRef<InverseRequirement> inverses,
971971 bool &isFirstReq, unsigned flags,
972972 llvm::function_ref<bool (const Requirement &)> filter);
973+ void printRequirementSignature (ProtocolDecl *owner,
974+ RequirementSignature sig,
975+ unsigned flags,
976+ TypeDecl *attachingTo);
973977 void printRequirement (const Requirement &req);
974978 void printRequirement (const InverseRequirement &inverse,
975979 bool forInherited);
@@ -1566,46 +1570,20 @@ bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req) {
15661570}
15671571
15681572void PrintAST::printInheritedFromRequirementSignature (ProtocolDecl *proto,
1569- TypeDecl* attachingTo) {
1570- Type attachedGP[1 ];
1571- if (auto proto = dyn_cast<ProtocolDecl>(attachingTo))
1572- attachedGP[0 ] = proto->getSelfInterfaceType ();
1573- else if (auto assoc = dyn_cast<AssociatedTypeDecl>(attachingTo))
1574- attachedGP[0 ] = assoc->getDeclaredInterfaceType ();
1575- else
1576- llvm_unreachable (" nonexhaustive" );
1577-
1578- printGenericSignature (
1579- proto->getRequirementSignatureAsGenericSignature (),
1580- PrintInherited,
1581- [&](const Requirement &req) {
1582- // Skip the inferred 'Self : AnyObject' constraint if this is an
1583- // @objc protocol.
1584- if ((req.getKind () == RequirementKind::Layout) &&
1585- req.getFirstType ()->isEqual (proto->getSelfInterfaceType ()) &&
1586- req.getLayoutConstraint ()->getKind () ==
1587- LayoutConstraintKind::Class &&
1588- proto->isObjC ()) {
1589- return false ;
1590- }
1591-
1592- auto location = bestRequirementPrintLocation (proto, req);
1593- return location.AttachedTo == attachingTo && !location.InWhereClause ;
1594- });
1573+ TypeDecl *attachingTo) {
1574+ printRequirementSignature (
1575+ proto, proto->getRequirementSignature (),
1576+ PrintInherited | PrintInverseRequirements,
1577+ attachingTo);
15951578}
15961579
15971580void PrintAST::printWhereClauseFromRequirementSignature (ProtocolDecl *proto,
15981581 TypeDecl *attachingTo) {
1599- unsigned flags = PrintRequirements;
1582+ unsigned flags = PrintRequirements | PrintInverseRequirements ;
16001583 if (isa<AssociatedTypeDecl>(attachingTo))
16011584 flags |= SwapSelfAndDependentMemberType;
1602- printGenericSignature (
1603- proto->getRequirementSignatureAsGenericSignature (),
1604- flags,
1605- [&](const Requirement &req) {
1606- auto location = bestRequirementPrintLocation (proto, req);
1607- return location.AttachedTo == attachingTo && location.InWhereClause ;
1608- });
1585+ printRequirementSignature (proto, proto->getRequirementSignature (), flags,
1586+ attachingTo);
16091587}
16101588
16111589// / A helper function to return the depth of a requirement.
@@ -1926,6 +1904,62 @@ void PrintAST::printSingleDepthOfGenericSignature(
19261904 Printer << " >" ;
19271905}
19281906
1907+ void PrintAST::printRequirementSignature (ProtocolDecl *owner,
1908+ RequirementSignature sig,
1909+ unsigned flags,
1910+ TypeDecl *attachingTo) {
1911+ SmallVector<Requirement, 2 > requirements;
1912+ SmallVector<InverseRequirement, 2 > inverses;
1913+
1914+ if (flags & PrintInverseRequirements) {
1915+ sig.getRequirementsWithInverses (owner, requirements, inverses);
1916+ } else {
1917+ requirements.append (sig.getRequirements ().begin (),
1918+ sig.getRequirements ().end ());
1919+ }
1920+
1921+ if (attachingTo) {
1922+ llvm::erase_if (requirements,
1923+ [&](Requirement req) {
1924+ // Skip the inferred 'Self : AnyObject' constraint if this is an
1925+ // @objc protocol.
1926+ if ((req.getKind () == RequirementKind::Layout) &&
1927+ req.getFirstType ()->isEqual (owner->getSelfInterfaceType ()) &&
1928+ req.getLayoutConstraint ()->getKind () ==
1929+ LayoutConstraintKind::Class &&
1930+ owner->isObjC ()) {
1931+ return true ;
1932+ }
1933+
1934+ auto location = bestRequirementPrintLocation (owner, req);
1935+ if (location.AttachedTo != attachingTo)
1936+ return true ;
1937+
1938+ if (flags & PrintRequirements)
1939+ return !location.InWhereClause ;
1940+
1941+ return location.InWhereClause ;
1942+ });
1943+
1944+ auto interfaceTy =
1945+ (isa<ProtocolDecl>(attachingTo)
1946+ ? cast<ProtocolDecl>(attachingTo)->getSelfInterfaceType ()
1947+ : cast<AssociatedTypeDecl>(attachingTo)->getDeclaredInterfaceType ());
1948+
1949+ llvm::erase_if (inverses,
1950+ [&](InverseRequirement req) {
1951+ // We print inverse requirements in the inheritance clause only.
1952+ if (flags & PrintRequirements)
1953+ return true ;
1954+ return !req.subject ->isEqual (interfaceTy);
1955+ });
1956+ }
1957+
1958+ printSingleDepthOfGenericSignature (
1959+ owner->getGenericSignature ().getGenericParams (), requirements, inverses,
1960+ flags, [&](Requirement) { return true ; });
1961+ }
1962+
19291963void PrintAST::printRequirement (const Requirement &req) {
19301964 SmallVector<Type, 2 > rootParameterPacks;
19311965 getTransformedType (req.getFirstType ())
@@ -2786,13 +2820,12 @@ void PrintAST::printSynthesizedExtension(Type ExtendedType,
27862820void PrintAST::printSynthesizedExtensionImpl (Type ExtendedType,
27872821 ExtensionDecl *ExtDecl) {
27882822 auto printRequirementsFrom = [&](ExtensionDecl *ED, bool &IsFirst) {
2789- // NOTE: As with normal extensions, we do not collapse defaults.
27902823 auto Sig = ED->getGenericSignature ();
27912824 printSingleDepthOfGenericSignature (Sig.getGenericParams (),
27922825 Sig.getRequirements (),
27932826 /* inverses=*/ {},
27942827 IsFirst,
2795- PrintRequirements,
2828+ PrintRequirements | PrintInverseRequirements ,
27962829 [](const Requirement &Req){
27972830 return true ;
27982831 });
@@ -7946,6 +7979,22 @@ void GenericSignature::print(ASTPrinter &Printer,
79467979 PrintAST (Printer, Opts).printGenericSignature (*this , flags);
79477980}
79487981
7982+ void RequirementSignature::print (ProtocolDecl *owner,
7983+ raw_ostream &OS,
7984+ const PrintOptions &Opts) const {
7985+ StreamPrinter Printer (OS);
7986+ print (owner, Printer, Opts);
7987+ }
7988+
7989+ void RequirementSignature::print (ProtocolDecl *owner,
7990+ ASTPrinter &Printer,
7991+ const PrintOptions &Opts) const {
7992+ auto flags = PrintAST::PrintParams | PrintAST::PrintRequirements;
7993+ if (Opts.PrintInverseRequirements )
7994+ flags |= PrintAST::PrintInverseRequirements;
7995+ PrintAST (Printer, Opts).printRequirementSignature (owner, *this , flags, nullptr );
7996+ }
7997+
79497998void Requirement::print (raw_ostream &os, const PrintOptions &opts) const {
79507999 StreamPrinter printer (os);
79518000 PrintAST (printer, opts).printRequirement (*this );
0 commit comments