Files
swift-mirror/lib/Sema/DerivedConformanceError.cpp
Jordan Rose 537954fb93 [AST] Rename several DeclContext methods to be clearer and shorter (#18798)
- getAsDeclOrDeclExtensionContext -> getAsDecl

This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.

- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)

These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point.  The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.

- getAsProtocolExtensionContext -> getExtendedProtocolDecl

Like the above, this didn't return the ExtensionDecl; it returned its
extended type.

This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
2018-08-17 14:05:24 -07:00

98 lines
3.0 KiB
C++

//===--- DerivedConformanceError.cpp - Derived Error ----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements implicit derivation of the Error
// protocol.
//
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
#include "DerivedConformances.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Stmt.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Module.h"
#include "swift/AST/Types.h"
using namespace swift;
static void deriveBodyBridgedNSError_enum_nsErrorDomain(
AbstractFunctionDecl *domainDecl) {
// enum SomeEnum {
// @derived
// static var _nsErrorDomain: String {
// return "ModuleName.SomeEnum"
// }
// }
auto M = domainDecl->getParentModule();
auto &C = M->getASTContext();
auto TC = domainDecl->getInnermostTypeContext();
auto ED = TC->getSelfEnumDecl();
std::string buffer = M->getNameStr();
buffer += ".";
buffer += ED->getNameStr();
StringRef value(C.AllocateCopy(buffer));
auto string = new (C) StringLiteralExpr(value, SourceRange(), /*implicit*/ true);
auto ret = new (C) ReturnStmt(SourceLoc(), string, /*implicit*/ true);
auto body = BraceStmt::create(C, SourceLoc(),
ASTNode(ret),
SourceLoc());
domainDecl->setBody(body);
}
static ValueDecl *
deriveBridgedNSError_enum_nsErrorDomain(DerivedConformance &derived) {
// enum SomeEnum {
// @derived
// static var _nsErrorDomain: String {
// return "\(self)"
// }
// }
// Note that for @objc enums the format is assumed to be "MyModule.SomeEnum".
// If this changes, please change PrintAsObjC as well.
ASTContext &C = derived.TC.Context;
auto stringTy = C.getStringDecl()->getDeclaredType();
// Define the property.
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
C.Id_nsErrorDomain, stringTy, stringTy, /*isStatic=*/true,
/*isFinal=*/true);
// Define the getter.
auto getterDecl = derived.addGetterToReadOnlyDerivedProperty(
derived.TC, propDecl, stringTy);
getterDecl->setBodySynthesizer(&deriveBodyBridgedNSError_enum_nsErrorDomain);
derived.addMembersToConformanceContext({getterDecl, propDecl, pbDecl});
return propDecl;
}
ValueDecl *DerivedConformance::deriveBridgedNSError(ValueDecl *requirement) {
if (!isa<EnumDecl>(Nominal))
return nullptr;
if (requirement->getBaseName() == TC.Context.Id_nsErrorDomain)
return deriveBridgedNSError_enum_nsErrorDomain(*this);
TC.diagnose(requirement->getLoc(), diag::broken_errortype_requirement);
return nullptr;
}