lib/Sema/DerivedConformanceCodingKey.cpp
/// Sets the body of the given constructor to initialize `self` based on the
/// value of the given string param.
///
/// \param initDecl The function whose body to set.
Sets the body of the given constructor to initialize `self` based on the
value of the given string param.

\param initDecl The function whose body to set.
Sets the body of the given constructor to initialize ` self ` based on the value of the given string param . \ param initDecl The function whose body to set .
static void
deriveBodyCodingKey_init_stringValue(AbstractFunctionDecl *initDecl, void *) {
  auto *parentDC = initDecl->getDeclContext();
  auto &C = parentDC->getASTContext();
  auto *enumDecl = parentDC->getSelfEnumDecl();
  Type enumType = parentDC->getDeclaredTypeInContext();
  auto elements = enumDecl->getAllElements();
  if (elements.empty() ) {
    deriveNilReturn(initDecl, nullptr);
    return;
  }
  auto *selfRef = DerivedConformance::createSelfDeclRef(initDecl);
  SmallVector<ASTNode, 4> cases;
  for (auto *elt : elements) {
    auto *litExpr = new (C) StringLiteralExpr(elt->getNameStr(), SourceRange(),
                                              true);
    auto *litPat = new (C) ExprPattern(litExpr, true, nullptr,
                                       nullptr);
    litPat->setImplicit();
    auto labelItem = CaseLabelItem(litPat);
    auto *eltRef = new (C) DeclRefExpr(elt, DeclNameLoc(), true);
    auto *metaTyRef = TypeExpr::createImplicit(enumType, C);
    auto *valueExpr = new (C) DotSyntaxCallExpr(eltRef, SourceLoc(), metaTyRef);
    auto *assignment = new (C) AssignExpr(selfRef, SourceLoc(), valueExpr,
                                          true);
    auto *body = BraceStmt::create(C, SourceLoc(), ASTNode(assignment),
                                   SourceLoc());
    cases.push_back(CaseStmt::create(C, SourceLoc(), labelItem, SourceLoc(),
                                     SourceLoc(), body,
                                      None));
  }
  auto *anyPat = new (C) AnyPattern(SourceLoc());
  anyPat->setImplicit();
  auto dfltLabelItem = CaseLabelItem::getDefault(anyPat);
  auto *dfltReturnStmt = new (C) FailStmt(SourceLoc(), SourceLoc());
  auto *dfltBody = BraceStmt::create(C, SourceLoc(), ASTNode(dfltReturnStmt),
                                     SourceLoc());
  cases.push_back(CaseStmt::create(C, SourceLoc(), dfltLabelItem, SourceLoc(),
                                   SourceLoc(), dfltBody,
                                    None));
  auto *stringValueDecl = initDecl->getParameters()->get(0);
  auto *stringValueRef = new (C) DeclRefExpr(stringValueDecl, DeclNameLoc(),
                                             true);
  auto *switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(),
                                        stringValueRef, SourceLoc(), cases,
                                        SourceLoc(), C);
  auto *body = BraceStmt::create(C, SourceLoc(), ASTNode(switchStmt),
                                 SourceLoc());
  initDecl->setBody(body);
}
static void deriveBodyCodingKey_init_stringValue ( AbstractFunctionDecl * initDecl , void * ) { auto * parentDC = initDecl -> getDeclContext ( ) ; auto & C = parentDC -> getASTContext ( ) ; auto * enumDecl = parentDC -> getSelfEnumDecl ( ) ; Type enumType = parentDC -> getDeclaredTypeInContext ( ) ; auto elements = enumDecl -> getAllElements ( ) ; if ( elements . empty ( ) ) { deriveNilReturn ( initDecl , nullptr ) ; return ; } auto * selfRef = DerivedConformance :: createSelfDeclRef ( initDecl ) ; SmallVector < ASTNode , 4 > cases ; for ( auto * elt : elements ) { auto * litExpr = new ( C ) StringLiteralExpr ( elt -> getNameStr ( ) , SourceRange ( ) , true ) ; auto * litPat = new ( C ) ExprPattern ( litExpr , true , nullptr , nullptr ) ; litPat -> setImplicit ( ) ; auto labelItem = CaseLabelItem ( litPat ) ; auto * eltRef = new ( C ) DeclRefExpr ( elt , DeclNameLoc ( ) , true ) ; auto * metaTyRef = TypeExpr :: createImplicit ( enumType , C ) ; auto * valueExpr = new ( C ) DotSyntaxCallExpr ( eltRef , SourceLoc ( ) , metaTyRef ) ; auto * assignment = new ( C ) AssignExpr ( selfRef , SourceLoc ( ) , valueExpr , true ) ; auto * body = BraceStmt :: create ( C , SourceLoc ( ) , ASTNode ( assignment ) , SourceLoc ( ) ) ; cases . push_back ( CaseStmt :: create ( C , SourceLoc ( ) , labelItem , SourceLoc ( ) , SourceLoc ( ) , body , None ) ) ; } auto * anyPat = new ( C ) AnyPattern ( SourceLoc ( ) ) ; anyPat -> setImplicit ( ) ; auto dfltLabelItem = CaseLabelItem :: getDefault ( anyPat ) ; auto * dfltReturnStmt = new ( C ) FailStmt ( SourceLoc ( ) , SourceLoc ( ) ) ; auto * dfltBody = BraceStmt :: create ( C , SourceLoc ( ) , ASTNode ( dfltReturnStmt ) , SourceLoc ( ) ) ; cases . push_back ( CaseStmt :: create ( C , SourceLoc ( ) , dfltLabelItem , SourceLoc ( ) , SourceLoc ( ) , dfltBody , None ) ) ; auto * stringValueDecl = initDecl -> getParameters ( ) -> get ( 0 ) ; auto * stringValueRef = new ( C ) DeclRefExpr ( stringValueDecl , DeclNameLoc ( ) , true ) ; auto * switchStmt = SwitchStmt :: create ( LabeledStmtInfo ( ) , SourceLoc ( ) , stringValueRef , SourceLoc ( ) , cases , SourceLoc ( ) , C ) ; auto * body = BraceStmt :: create ( C , SourceLoc ( ) , ASTNode ( switchStmt ) , SourceLoc ( ) ) ; initDecl -> setBody ( body ) ; }
Sets the body of the given constructor to initialize `self` based on the
value of the given string param.
Sets the body of the given constructor to initialize ` self ` based on the value of the given string param .
// enum SomeEnum { //   case A, B, C //   @derived init?(stringValue: String) { //     switch stringValue { //     case "A": //       self = .A //     case "B": //       self = .B //     case "C": //       self = .C //     default: //       return nil //     } //   } // } /* empty enum */ /*Implicit=*/ /*IsResolved=*/ /*Implicit=*/ /*Implicit=*/ /*case body var decls*/ /*case body var decls*/ /*Implicit=*/