2222#include " swift/AST/Expr.h"
2323#include " swift/AST/Module.h"
2424#include " swift/AST/Types.h"
25+ #include " swift/AST/SwiftNameTranslation.h"
2526
2627using namespace swift ;
28+ using namespace swift ::objc_translation;
2729
2830static void deriveBodyBridgedNSError_enum_nsErrorDomain (
29- AbstractFunctionDecl *domainDecl, void *) {
31+ AbstractFunctionDecl *domainDecl, void *) {
32+ // enum SomeEnum {
33+ // @derived
34+ // static var _nsErrorDomain: String {
35+ // return String(reflecting: self)
36+ // }
37+ // }
38+
39+ auto M = domainDecl->getParentModule ();
40+ auto &C = M->getASTContext ();
41+ auto self = domainDecl->getImplicitSelfDecl ();
42+
43+ auto selfRef = new (C) DeclRefExpr (self, DeclNameLoc (), /* implicit*/ true );
44+ auto stringType = TypeExpr::createForDecl (SourceLoc (), C.getStringDecl (),
45+ domainDecl, /* implicit*/ true );
46+ auto initReflectingCall =
47+ CallExpr::createImplicit (C, stringType,
48+ { selfRef }, { C.getIdentifier (" reflecting" ) });
49+ auto ret =
50+ new (C) ReturnStmt (SourceLoc (), initReflectingCall, /* implicit*/ true );
51+
52+ auto body = BraceStmt::create (C, SourceLoc (), ASTNode (ret), SourceLoc ());
53+
54+ domainDecl->setBody (body);
55+ }
56+
57+ static void deriveBodyBridgedNSError_printAsObjCEnum_nsErrorDomain (
58+ AbstractFunctionDecl *domainDecl, void *) {
3059 // enum SomeEnum {
3160 // @derived
3261 // static var _nsErrorDomain: String {
@@ -39,10 +68,7 @@ static void deriveBodyBridgedNSError_enum_nsErrorDomain(
3968 auto TC = domainDecl->getInnermostTypeContext ();
4069 auto ED = TC->getSelfEnumDecl ();
4170
42- std::string buffer = M->getNameStr ();
43- buffer += " ." ;
44- buffer += ED->getNameStr ();
45- StringRef value (C.AllocateCopy (buffer));
71+ StringRef value (C.AllocateCopy (getErrorDomainStringForObjC (ED)));
4672
4773 auto string = new (C) StringLiteralExpr (value, SourceRange (), /* implicit*/ true );
4874 auto ret = new (C) ReturnStmt (SourceLoc (), string, /* implicit*/ true );
@@ -53,17 +79,15 @@ static void deriveBodyBridgedNSError_enum_nsErrorDomain(
5379}
5480
5581static ValueDecl *
56- deriveBridgedNSError_enum_nsErrorDomain (DerivedConformance &derived) {
82+ deriveBridgedNSError_enum_nsErrorDomain (DerivedConformance &derived,
83+ void (*synthesizer)(AbstractFunctionDecl *, void *)) {
5784 // enum SomeEnum {
5885 // @derived
5986 // static var _nsErrorDomain: String {
60- // return "\(self)"
87+ // ...
6188 // }
6289 // }
6390
64- // Note that for @objc enums the format is assumed to be "MyModule.SomeEnum".
65- // If this changes, please change PrintAsObjC as well.
66-
6791 ASTContext &C = derived.TC .Context ;
6892
6993 auto stringTy = C.getStringDecl ()->getDeclaredType ();
@@ -78,7 +102,7 @@ deriveBridgedNSError_enum_nsErrorDomain(DerivedConformance &derived) {
78102 // Define the getter.
79103 auto getterDecl = derived.addGetterToReadOnlyDerivedProperty (
80104 derived.TC , propDecl, stringTy);
81- getterDecl->setBodySynthesizer (&deriveBodyBridgedNSError_enum_nsErrorDomain );
105+ getterDecl->setBodySynthesizer (synthesizer );
82106
83107 derived.addMembersToConformanceContext ({getterDecl, propDecl, pbDecl});
84108
@@ -89,8 +113,17 @@ ValueDecl *DerivedConformance::deriveBridgedNSError(ValueDecl *requirement) {
89113 if (!isa<EnumDecl>(Nominal))
90114 return nullptr ;
91115
92- if (requirement->getBaseName () == TC.Context .Id_nsErrorDomain )
93- return deriveBridgedNSError_enum_nsErrorDomain (*this );
116+ if (requirement->getBaseName () == TC.Context .Id_nsErrorDomain ) {
117+ auto synthesizer = deriveBodyBridgedNSError_enum_nsErrorDomain;
118+
119+ auto scope = Nominal->getFormalAccessScope (Nominal->getModuleScopeContext ());
120+ if (scope.isPublic () || scope.isInternal ())
121+ // PrintAsObjC may print this domain, so we should make sure we use the
122+ // same string it will.
123+ synthesizer = deriveBodyBridgedNSError_printAsObjCEnum_nsErrorDomain;
124+
125+ return deriveBridgedNSError_enum_nsErrorDomain (*this , synthesizer);
126+ }
94127
95128 TC.diagnose (requirement->getLoc (), diag::broken_errortype_requirement);
96129 return nullptr ;
0 commit comments