| //===--- TypeCheckObjC.h - Type Checking for ObjC interop -------*- C++ -*-===// |
| // |
| // 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 provides utilities for type-checking interoperability with |
| // Objective-C. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef SWIFT_SEMA_TYPE_CHECK_OBJC_H |
| #define SWIFT_SEMA_TYPE_CHECK_OBJC_H |
| |
| #include "swift/AST/ForeignErrorConvention.h" |
| #include "llvm/ADT/Optional.h" |
| |
| namespace swift { |
| |
| class AbstractFunctionDecl; |
| class ASTContext; |
| class SubscriptDecl; |
| class TypeChecker; |
| class ValueDecl; |
| class VarDecl; |
| |
| using llvm::Optional; |
| |
| /// Describes the reason why are we trying to apply @objc to a declaration. |
| /// |
| /// Should only affect diagnostics. If you change this enum, also change |
| /// the OBJC_ATTR_SELECT macro in DiagnosticsSema.def. |
| class ObjCReason { |
| public: |
| // The kind of reason. |
| enum Kind { |
| /// Has the '@cdecl' attribute. |
| ExplicitlyCDecl, |
| /// Has the 'dynamic' modifier. |
| ExplicitlyDynamic, |
| /// Has an explicit '@objc' attribute. |
| ExplicitlyObjC, |
| /// Has an explicit '@IBOutlet' attribute. |
| ExplicitlyIBOutlet, |
| /// Has an explicit '@IBAction' attribute. |
| ExplicitlyIBAction, |
| /// Has an explicit '@NSManaged' attribute. |
| ExplicitlyNSManaged, |
| /// Is a member of an @objc protocol. |
| MemberOfObjCProtocol, |
| /// Implicitly-introduced @objc. |
| ImplicitlyObjC, |
| /// Is an override of an @objc member. |
| OverridesObjC, |
| /// Is a witness to an @objc protocol requirement. |
| WitnessToObjC, |
| /// Has an explicit '@IBInspectable' attribute. |
| ExplicitlyIBInspectable, |
| /// Has an explicit '@GKInspectable' attribute. |
| ExplicitlyGKInspectable, |
| /// Is it a member of an @objc extension of a class. |
| MemberOfObjCExtension, |
| |
| // These kinds do not appear in diagnostics. |
| |
| /// Is it a member of an @objcMembers class. |
| MemberOfObjCMembersClass, |
| /// A member of an Objective-C-defined class or subclass. |
| MemberOfObjCSubclass, |
| /// Is a member of an @objc enum. |
| ElementOfObjCEnum, |
| /// An accessor to a property. |
| Accessor, |
| }; |
| |
| private: |
| Kind kind; |
| |
| /// When the kind is \c WitnessToObjC, the requirement being witnessed. |
| ValueDecl * decl = nullptr; |
| |
| ObjCReason(Kind kind, ValueDecl *decl) : kind(kind), decl(decl) { } |
| |
| public: |
| /// Implicit conversion from the trivial reason kinds. |
| ObjCReason(Kind kind) : kind(kind) { |
| assert(kind != WitnessToObjC && "Use ObjCReason::witnessToObjC()"); |
| } |
| |
| /// Retrieve the kind of requirement. |
| operator Kind() const { return kind; } |
| |
| /// Form a reason specifying that we have a witness to the given @objc |
| /// requirement. |
| static ObjCReason witnessToObjC(ValueDecl *requirement) { |
| return ObjCReason(WitnessToObjC, requirement); |
| } |
| |
| /// When the entity should be @objc because it is a witness to an @objc |
| /// requirement, retrieve the requirement. |
| ValueDecl *getObjCRequirement() const { |
| assert(kind == WitnessToObjC); |
| return decl; |
| } |
| }; |
| |
| /// Determine whether we should diagnose conflicts due to inferring @objc |
| /// with this particular reason. |
| bool shouldDiagnoseObjCReason(ObjCReason reason, ASTContext &ctx); |
| |
| /// Return the %select discriminator for the OBJC_ATTR_SELECT macro used to |
| /// complain about the correct attribute during @objc inference. |
| unsigned getObjCDiagnosticAttrKind(ObjCReason reason); |
| |
| /// Determine whether the given function can be represented in Objective-C, |
| /// and figure out its foreign error convention (if any). |
| bool isRepresentableInObjC(const AbstractFunctionDecl *AFD, |
| ObjCReason Reason, |
| Optional<ForeignErrorConvention> &errorConvention); |
| |
| /// Determine whether the given variable can be represented in Objective-C. |
| bool isRepresentableInObjC(const VarDecl *VD, ObjCReason Reason); |
| |
| /// Determine whether the given subscript can be represented in Objective-C. |
| bool isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason); |
| |
| /// Check whether the given declaration can be represented in Objective-C. |
| bool canBeRepresentedInObjC(const ValueDecl *decl); |
| |
| /// Check that specific, known bridging functions are fully type-checked. |
| /// |
| /// NOTE: This is only here to support the --enable-source-import hack. |
| void checkBridgedFunctions(ASTContext &ctx); |
| |
| } // end namespace swift |
| |
| #endif // SWIFT_SEMA_TYPE_CHECK_OBJC_H |