diff --git a/apinotes/Accelerate.apinotes b/apinotes/Accelerate.apinotes deleted file mode 100644 index 12e48ef89e5..00000000000 --- a/apinotes/Accelerate.apinotes +++ /dev/null @@ -1,61 +0,0 @@ -Name: Accelerate -Enumerators: -- Name: BNNSDataTypeFloatBit - Availability: nonswift -- Name: BNNSDataTypeIntBit - Availability: nonswift -- Name: BNNSDataTypeUIntBit - Availability: nonswift -- Name: BNNSDataTypeIndexedBit - Availability: nonswift -- Name: BNNSDataTypeFloat16 - SwiftPrivate: true -- Name: BNNSDataTypeFloat32 - SwiftPrivate: true -- Name: BNNSDataTypeInt8 - SwiftPrivate: true -- Name: BNNSDataTypeInt16 - SwiftPrivate: true -- Name: BNNSDataTypeInt32 - SwiftPrivate: true -- Name: BNNSDataTypeUInt8 - SwiftPrivate: true -- Name: BNNSDataTypeUInt16 - SwiftPrivate: true -- Name: BNNSDataTypeUInt32 - SwiftPrivate: true -- Name: BNNSDataTypeIndexed8 - SwiftPrivate: true - -- Name: BNNSPoolingFunctionMax - SwiftPrivate: true -- Name: BNNSPoolingFunctionAverage - SwiftPrivate: true - -- Name: BNNSActivationFunctionIdentity - SwiftPrivate: true -- Name: BNNSActivationFunctionRectifiedLinear - SwiftPrivate: true -- Name: BNNSActivationFunctionLeakyRectifiedLinear - SwiftPrivate: true -- Name: BNNSActivationFunctionSigmoid - SwiftPrivate: true -- Name: BNNSActivationFunctionTanh - SwiftPrivate: true -- Name: BNNSActivationFunctionScaledTanh - SwiftPrivate: true -- Name: BNNSActivationFunctionAbs - SwiftPrivate: true -- Name: BNNSActivationFunctionLinear - SwiftPrivate: true -- Name: BNNSActivationFunctionClamp - SwiftPrivate: true -- Name: BNNSActivationFunctionIntegerLinearSaturate - SwiftPrivate: true -- Name: BNNSActivationFunctionIntegerLinearSaturatePerChannel - SwiftPrivate: true -- Name: BNNSActivationFunctionSoftmax - SwiftPrivate: true - -- Name: BNNSFlagsUseClientPtr - SwiftPrivate: true diff --git a/apinotes/CMakeLists.txt b/apinotes/CMakeLists.txt index add121dad40..ab1ecd6811d 100644 --- a/apinotes/CMakeLists.txt +++ b/apinotes/CMakeLists.txt @@ -1,7 +1,5 @@ set(sources - Accelerate.apinotes Dispatch.apinotes - ScriptingBridge.apinotes os.apinotes ) diff --git a/apinotes/ScriptingBridge.apinotes b/apinotes/ScriptingBridge.apinotes deleted file mode 100644 index a02ce246d25..00000000000 --- a/apinotes/ScriptingBridge.apinotes +++ /dev/null @@ -1,5 +0,0 @@ ---- -Name: ScriptingBridge -Classes: -- Name: SBElementArray - SwiftImportAsNonGeneric: true diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index 2344582806f..de90e54a3bc 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -394,6 +394,7 @@ DECL_ATTR(_private, PrivateImport, SIMPLE_DECL_ATTR(_alwaysEmitIntoClient, AlwaysEmitIntoClient, OnVar | OnSubscript | OnAbstractFunction | UserInaccessible, 83) + SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly, OnImport | UserInaccessible, 84) @@ -407,6 +408,10 @@ SIMPLE_DECL_ATTR(_disfavoredOverload, DisfavoredOverload, OnAbstractFunction | OnVar | OnSubscript | UserInaccessible, 87) +SIMPLE_DECL_ATTR(IBSegueAction, IBSegueAction, + OnFunc, + 95) + #undef TYPE_ATTR #undef DECL_ATTR_ALIAS #undef CONTEXTUAL_DECL_ATTR_ALIAS diff --git a/include/swift/AST/AvailabilitySpec.h b/include/swift/AST/AvailabilitySpec.h index 1f02cdf7e8f..05c0752bffa 100644 --- a/include/swift/AST/AvailabilitySpec.h +++ b/include/swift/AST/AvailabilitySpec.h @@ -83,7 +83,12 @@ public: /// The required platform. PlatformKind getPlatform() const { return Platform; } SourceLoc getPlatformLoc() const { return PlatformLoc; } - + + /// Returns true when the constraint is for a platform that was not + /// recognized. This enables better recovery during parsing but should never + /// be true after parsing is completed. + bool isUnrecognizedPlatform() const { return Platform == PlatformKind::none; } + // The platform version to compare against. llvm::VersionTuple getVersion() const { return Version; } SourceRange getVersionSrcRange() const { return VersionSrcRange; } diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 9c01a48579c..a05cd74c9a6 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -6069,8 +6069,8 @@ public: /// True if the function is a defer body. bool isDeferBody() const; - /// Perform basic checking to determine whether the @IBAction attribute can - /// be applied to this function. + /// Perform basic checking to determine whether the @IBAction or + /// @IBSegueAction attribute can be applied to this function. bool isPotentialIBActionTarget() const; }; diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index e1948e35095..22658a6b506 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1575,8 +1575,8 @@ ERROR(avail_query_expected_version_number,PointsToFirstBadToken, ERROR(avail_query_expected_rparen,PointsToFirstBadToken, "expected ')' in availability query", ()) -ERROR(avail_query_unrecognized_platform_name, - PointsToFirstBadToken, "unrecognized platform name %0", (Identifier)) +WARNING(avail_query_unrecognized_platform_name, + PointsToFirstBadToken, "unrecognized platform name %0", (Identifier)) ERROR(avail_query_disallowed_operator, PointsToFirstBadToken, "'%0' cannot be used in an availability condition", (StringRef)) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 44026fe5b1d..daeb29c7009 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1179,17 +1179,25 @@ ERROR(invalid_ibdesignable_extension,none, ERROR(invalid_ibinspectable,none, "only instance properties can be declared @%0", (StringRef)) ERROR(invalid_ibaction_decl,none, - "only instance methods can be declared @IBAction", ()) + "only instance methods can be declared @%0", (StringRef)) ERROR(invalid_ibaction_result,none, - "methods declared @IBAction must return 'Void' (not %0)", (Type)) + "methods declared @%0 must %select{|not }1return a value", (StringRef, bool)) ERROR(invalid_ibaction_argument_count,none, - "@IBAction methods %select{must have a single argument" - "|can only have up to 2 arguments}0", (bool)) -ERROR(ibaction_nonobjc_class_argument,none, - "argument to @IBAction method cannot have non-'@objc' class type %0", - (Type)) -ERROR(ibaction_nonobject_argument,none, - "argument to @IBAction method cannot have non-object type %0", (Type)) + "@%0 methods must have %1 to %2 arguments", + (StringRef, int, int)) +ERROR(invalid_ibaction_argument_count_exact,none, + "@%0 methods must have %2 argument%s2", + (StringRef, int, int)) +ERROR(invalid_ibaction_argument_count_max,none, + "@%0 methods must have at most %2 argument%s2", + (StringRef, int, int)) +ERROR(ibsegueaction_objc_method_family,none, + "@%0 method cannot have selector %1 because it has special memory " + "management behavior", (StringRef, ObjCSelector)) +NOTE(fixit_rename_in_swift,none, + "change Swift name to %0", (DeclName)) +NOTE(fixit_rename_in_objc,none, + "change Objective-C selector to %0", (ObjCSelector)) ERROR(no_objc_tagged_pointer_not_class_protocol,none, "@unsafe_no_objc_tagged_pointer can only be applied to class protocols", ()) @@ -3674,8 +3682,8 @@ ERROR(objc_in_generic_extension,none, "extensions of %select{classes from generic context|generic classes}0 " "cannot contain '@objc' members", (bool)) ERROR(objc_in_resilient_extension,none, - "extensions of classes built with library evolution support " - "cannot contain '@objc' members", ()) + "'@objc' %0 in extension of subclass of %1 requires %2 %3", + (DescriptiveDeclKind, Identifier, StringRef, llvm::VersionTuple)) ERROR(objc_operator, none, "operator methods cannot be declared @objc", ()) ERROR(objc_operator_proto, none, @@ -3697,9 +3705,8 @@ ERROR(objc_for_generic_class,none, "generic subclasses of '@objc' classes cannot have an explicit '@objc' " "because they are not directly visible from Objective-C", ()) ERROR(objc_for_resilient_class,none, - "classes built with library evolution support cannot have explicit " - "'@objc' subclasses because they are not directly " - "visible from Objective-C", ()) + "explicit '@objc' on subclass of %0 requires %1 %2", + (Identifier, StringRef, llvm::VersionTuple)) ERROR(objc_getter_for_nonobjc_property,none, "'@objc' getter for non-'@objc' property", ()) ERROR(objc_getter_for_nonobjc_subscript,none, @@ -3740,7 +3747,7 @@ ERROR(objc_extension_not_class,none, "'@objc' can only be applied to an extension of a class", ()) // If you change this, also change enum ObjCReason -#define OBJC_ATTR_SELECT "select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}" +#define OBJC_ATTR_SELECT "select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}" WARNING(attribute_meaningless_when_nonobjc,none, "'@%0' attribute is meaningless on a property that cannot be " diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 4515a904565..d15dfa78219 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -305,11 +305,6 @@ namespace swift { /// set to true. bool ExperimentalDependenciesIncludeIntrafileOnes = false; - /// Enable experimental support for emitting Objective-C resilient class - /// stubs. This is a language option since it also determines if we admit - /// @objc members in extensions of classes with resilient ancestry. - bool EnableObjCResilientClassStubs = false; - /// Sets the target we are building for and updates platform conditions /// to match. /// @@ -403,6 +398,15 @@ namespace swift { // - watchOS 5.2 bool doesTargetSupportObjCGetClassHook() const; + // The following deployment targets ship an Objective-C runtime supporting + // the objc_loadClassref() entry point: + // + // - macOS 10.15 + // - iOS 13 + // - tvOS 13 + // - watchOS 6 + bool doesTargetSupportObjCClassStubs() const; + /// Returns true if the given platform condition argument represents /// a supported target operating system. /// diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 74507d9c850..6a1ec00c07b 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -220,13 +220,16 @@ AvailabilityContext AvailabilityInference::inferForType(Type t) { AvailabilityContext ASTContext::getOpaqueTypeAvailability() { auto target = LangOpts.Target; - if (target.isMacOSX() - || target.isiOS() - || target.isWatchOS()) { - // TODO: Update with OS versions that ship with runtime support + if (target.isMacOSX()) { return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(9999,0,0))); + VersionRange::allGTE(llvm::VersionTuple(10,15,0))); + } else if (target.isiOS()) { + return AvailabilityContext( + VersionRange::allGTE(llvm::VersionTuple(13,0,0))); + } else if (target.isWatchOS()) { + return AvailabilityContext( + VersionRange::allGTE(llvm::VersionTuple(6,0,0))); + } else { + return AvailabilityContext::alwaysAvailable(); } - - return AvailabilityContext::alwaysAvailable(); } diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index a35121f115a..78b9df90030 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -284,11 +284,24 @@ bool LangOptions::doesTargetSupportObjCMetadataUpdateCallback() const { if (Target.isWatchOS()) return !Target.isOSVersionLT(5, 2); - // If we're running on a non-Apple platform, we still want to allow running - // tests that -enable-objc-interop. + // Don't assert if we're running on a non-Apple platform; we still + // want to allow running tests that -enable-objc-interop. return false; } bool LangOptions::doesTargetSupportObjCGetClassHook() const { return doesTargetSupportObjCMetadataUpdateCallback(); } + +bool LangOptions::doesTargetSupportObjCClassStubs() const { + if (Target.isMacOSX()) + return !Target.isMacOSXVersionLT(10, 15); + if (Target.isiOS()) // also returns true on tvOS + return !Target.isOSVersionLT(13); + if (Target.isWatchOS()) + return !Target.isOSVersionLT(6); + + // Don't assert if we're running on a non-Apple platform; we still + // want to allow running tests that -enable-objc-interop. + return false; +} diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 9d872936936..af44228b91a 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4169,6 +4169,8 @@ namespace { new (Impl.SwiftContext) IBActionAttr(/*IsImplicit=*/false)); } + // FIXME: Is there an IBSegueAction equivalent? + // Check whether there's some special method to import. if (!forceClassMethod) { if (dc == Impl.importDeclContextOf(decl, decl->getDeclContext()) && diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 2819d5ef439..adf432631f2 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -484,9 +484,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.DisableConstraintSolverPerformanceHacks |= Args.hasArg(OPT_disable_constraint_solver_performance_hacks); - Opts.EnableObjCResilientClassStubs = - Args.hasArg(OPT_enable_objc_resilient_class_stubs); - // Must be processed after any other language options that could affect // platform conditions. bool UnsupportedOS, UnsupportedArch; diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp index f9f4d84b37a..d7ad8d47893 100644 --- a/lib/Index/Index.cpp +++ b/lib/Index/Index.cpp @@ -1244,17 +1244,24 @@ bool IndexSwiftASTWalker::initFuncDeclIndexSymbol(FuncDecl *D, Info.roles |= (SymbolRoleSet)SymbolRole::Dynamic; } - if (D->getAttrs().hasAttribute()) { - // Relate with type of the first parameter using RelationIBTypeOf. - if (D->hasImplicitSelfDecl()) { - auto paramList = D->getParameters(); - if (!paramList->getArray().empty()) { - auto param = paramList->get(0); - if (auto nominal = param->getType()->getAnyNominal()) { - addRelation(Info, (SymbolRoleSet) SymbolRole::RelationIBTypeOf, nominal); - } - } + if (D->hasImplicitSelfDecl()) { + // If this is an @IBAction or @IBSegueAction method, find the sender + // parameter (if present) and relate the method to its type. + ParamDecl *senderParam = nullptr; + + auto paramList = D->getParameters(); + if (D->getAttrs().hasAttribute()) { + if (paramList->size() > 0) + senderParam = paramList->get(0); + } else if (D->getAttrs().hasAttribute()) { + if (paramList->size() > 1) + senderParam = paramList->get(1); } + + if (senderParam) + if (auto nominal = senderParam->getType()->getAnyNominal()) + addRelation(Info, (SymbolRoleSet) SymbolRole::RelationIBTypeOf, + nominal); } if (auto Group = D->getGroupName()) diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp index 12b55f23a85..6ca05d2fcb9 100644 --- a/lib/Index/IndexSymbol.cpp +++ b/lib/Index/IndexSymbol.cpp @@ -84,7 +84,8 @@ static bool isUnitTest(const ValueDecl *D) { static void setFuncSymbolInfo(const FuncDecl *FD, SymbolInfo &sym) { sym.Kind = SymbolKind::Function; - if (FD->getAttrs().hasAttribute()) + if (FD->getAttrs().hasAttribute() || + FD->getAttrs().hasAttribute()) sym.Properties |= SymbolProperty::IBAnnotated; if (isUnitTest(FD)) diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 8ac1515c5da..2577b094314 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -3649,7 +3649,7 @@ Parser::parsePlatformVersionConstraintSpec() { if (!Platform.hasValue() || Platform.getValue() == PlatformKind::none) { diagnose(Tok, diag::avail_query_unrecognized_platform_name, PlatformIdentifier); - return nullptr; + Platform = PlatformKind::none; } // Register the platform name as a keyword token. diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index c8a6ef62b40..decb90dc431 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1214,9 +1214,10 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result, } } -/// Validate availability spec list, emitting diagnostics if necessary. +/// Validate availability spec list, emitting diagnostics if necessary and removing +/// specs for unrecognized platforms. static void validateAvailabilitySpecList(Parser &P, - ArrayRef Specs) { + SmallVectorImpl &Specs) { llvm::SmallSet Platforms; bool HasOtherPlatformSpec = false; @@ -1228,7 +1229,9 @@ static void validateAvailabilitySpecList(Parser &P, return; } + SmallVector RecognizedSpecs; for (auto *Spec : Specs) { + RecognizedSpecs.push_back(Spec); if (isa(Spec)) { HasOtherPlatformSpec = true; continue; @@ -1243,6 +1246,13 @@ static void validateAvailabilitySpecList(Parser &P, } auto *VersionSpec = cast(Spec); + // We keep specs for unrecognized platforms around for error recovery + // during parsing but remove them once parsing is completed. + if (VersionSpec->isUnrecognizedPlatform()) { + RecognizedSpecs.pop_back(); + continue; + } + bool Inserted = Platforms.insert(VersionSpec->getPlatform()).second; if (!Inserted) { // Rule out multiple version specs referring to the same platform. @@ -1260,6 +1270,8 @@ static void validateAvailabilitySpecList(Parser &P, P.diagnose(InsertWildcardLoc, diag::availability_query_wildcard_required) .fixItInsertAfter(InsertWildcardLoc, ", *"); } + + Specs = RecognizedSpecs; } // #available(...) diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp index 8466486db4c..2e619454823 100644 --- a/lib/PrintAsObjC/PrintAsObjC.cpp +++ b/lib/PrintAsObjC/PrintAsObjC.cpp @@ -594,6 +594,11 @@ private: } else if (clangMethod && isNSUInteger(clangMethod->getReturnType())) { os << "NSUInteger"; } else { + // IBSegueAction is placed before whatever return value is chosen. + if (AFD->getAttrs().hasAttribute()) { + os << "IBSegueAction "; + } + OptionalTypeKind kind; Type objTy; std::tie(objTy, kind) = getObjectTypeAndOptionality(AFD, resultTy); @@ -2736,6 +2741,9 @@ public: "#else\n" "# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)\n" "#endif\n" + "#if !defined(IBSegueAction)\n" + "# define IBSegueAction\n" + "#endif\n" ; static_assert(SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4, "need to add SIMD typedefs here if max elements is increased"); diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 29d4e0cf443..e8c59e3d408 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -32,6 +32,7 @@ #include "swift/Sema/IDETypeChecking.h" #include "clang/Basic/CharInfo.h" #include "llvm/Support/Debug.h" +#include "clang/Basic/CharInfo.h" using namespace swift; @@ -224,6 +225,7 @@ public: } void visitIBActionAttr(IBActionAttr *attr); + void visitIBSegueActionAttr(IBSegueActionAttr *attr); void visitLazyAttr(LazyAttr *attr); void visitIBDesignableAttr(IBDesignableAttr *attr); void visitIBInspectableAttr(IBInspectableAttr *attr); @@ -335,10 +337,19 @@ void AttributeEarlyChecker::visitDynamicAttr(DynamicAttr *attr) { void AttributeEarlyChecker::visitIBActionAttr(IBActionAttr *attr) { - // Only instance methods returning () can be IBActions. + // Only instance methods can be IBActions. const FuncDecl *FD = cast(D); if (!FD->isPotentialIBActionTarget()) - diagnoseAndRemoveAttr(attr, diag::invalid_ibaction_decl); + diagnoseAndRemoveAttr(attr, diag::invalid_ibaction_decl, + attr->getAttrName()); +} + +void AttributeEarlyChecker::visitIBSegueActionAttr(IBSegueActionAttr *attr) { + // Only instance methods can be IBActions. + const FuncDecl *FD = cast(D); + if (!FD->isPotentialIBActionTarget()) + diagnoseAndRemoveAttr(attr, diag::invalid_ibaction_decl, + attr->getAttrName()); } void AttributeEarlyChecker::visitIBDesignableAttr(IBDesignableAttr *attr) { @@ -802,6 +813,7 @@ public: void visitFinalAttr(FinalAttr *attr); void visitIBActionAttr(IBActionAttr *attr); + void visitIBSegueActionAttr(IBSegueActionAttr *attr); void visitNSCopyingAttr(NSCopyingAttr *attr); void visitRequiredAttr(RequiredAttr *attr); void visitRethrowsAttr(RethrowsAttr *attr); @@ -846,34 +858,6 @@ public: } // end anonymous namespace -static bool checkObjectOrOptionalObjectType(TypeChecker &TC, Decl *D, - ParamDecl *param) { - Type ty = param->getType(); - if (auto unwrapped = ty->getOptionalObjectType()) - ty = unwrapped; - - if (auto classDecl = ty->getClassOrBoundGenericClass()) { - // @objc class types are okay. - if (!classDecl->isObjC()) { - TC.diagnose(D, diag::ibaction_nonobjc_class_argument, - param->getType()) - .highlight(param->getSourceRange()); - return true; - } - } else if (ty->isObjCExistentialType() || ty->isAny()) { - // @objc existential types are okay, as is Any. - // Nothing to do. - } else { - // No other types are permitted. - TC.diagnose(D, diag::ibaction_nonobject_argument, - param->getType()) - .highlight(param->getSourceRange()); - return true; - } - - return false; -} - static bool isiOS(TypeChecker &TC) { return TC.getLangOpts().Target.isiOS(); } @@ -1100,72 +1084,124 @@ visitDynamicMemberLookupAttr(DynamicMemberLookupAttr *attr) { } } +static bool +validateIBActionSignature(TypeChecker &TC, DeclAttribute *attr, FuncDecl *FD, + unsigned minParameters, unsigned maxParameters, + bool hasVoidResult = true) { + bool valid = true; + + auto arity = FD->getParameters()->size(); + auto resultType = FD->getResultInterfaceType(); + + if (arity < minParameters || arity > maxParameters) { + auto diagID = diag::invalid_ibaction_argument_count; + if (minParameters == maxParameters) + diagID = diag::invalid_ibaction_argument_count_exact; + else if (minParameters == 0) + diagID = diag::invalid_ibaction_argument_count_max; + TC.diagnose(FD, diagID, attr->getAttrName(), minParameters, maxParameters); + valid = false; + } + + if (resultType->isVoid() != hasVoidResult) { + TC.diagnose(FD, diag::invalid_ibaction_result, attr->getAttrName(), + hasVoidResult); + valid = false; + } + + // We don't need to check here that parameter or return types are + // ObjC-representable; IsObjCRequest will validate that. + + if (!valid) + attr->setInvalid(); + return valid; +} + void AttributeChecker::visitIBActionAttr(IBActionAttr *attr) { - // IBActions instance methods must have type Class -> (...) -> (). auto *FD = cast(D); - Type CurriedTy = FD->getMethodInterfaceType(); - Type ResultTy = CurriedTy->castTo()->getResult(); - if (!ResultTy->isEqual(TupleType::getEmpty(TC.Context))) { - TC.diagnose(D, diag::invalid_ibaction_result, ResultTy); - attr->setInvalid(); + + if (isRelaxedIBAction(TC)) + // iOS, tvOS, and watchOS allow 0-2 parameters to an @IBAction method. + validateIBActionSignature(TC, attr, FD, /*minParams=*/0, /*maxParams=*/2); + else + // macOS allows 1 parameter to an @IBAction method. + validateIBActionSignature(TC, attr, FD, /*minParams=*/1, /*maxParams=*/1); +} + +void AttributeChecker::visitIBSegueActionAttr(IBSegueActionAttr *attr) { + auto *FD = cast(D); + if (!validateIBActionSignature(TC, attr, FD, + /*minParams=*/1, /*maxParams=*/3, + /*hasVoidResult=*/false)) return; - } - auto paramList = FD->getParameters(); - bool relaxedIBActionUsedOnOSX = false; - bool Valid = true; - switch (paramList->size()) { - case 0: - // (iOS only) No arguments. - if (!isRelaxedIBAction(TC)) { - relaxedIBActionUsedOnOSX = true; - break; - } + // If the IBSegueAction method's selector belongs to one of the ObjC method + // families (like -newDocumentSegue: or -copyScreen), it would return the + // object at +1, but the caller would expect it to be +0 and would therefore + // leak it. + // + // To prevent that, diagnose if the selector belongs to one of the method + // families and suggest that the user change the Swift name or Obj-C selector. + auto currentSelector = FD->getObjCSelector(); + + SmallString<32> prefix("make"); + + switch (currentSelector.getSelectorFamily()) { + case ObjCSelectorFamily::None: + // No error--exit early. + return; + + case ObjCSelectorFamily::Alloc: + case ObjCSelectorFamily::Init: + case ObjCSelectorFamily::New: + // Fix-it will replace the "alloc"/"init"/"new" in the selector with "make". break; - case 1: - // One argument. May be a scalar on iOS/watchOS (because of WatchKit). - if (isRelaxedIBAction(TC)) { - // Do a rough check to allow any ObjC-representable struct or enum type - // on iOS. - Type ty = paramList->get(0)->getType(); - if (auto nominal = ty->getAnyNominal()) - if (isa(nominal) || isa(nominal)) - if (!nominal->isOptionalDecl()) - if (ty->isTriviallyRepresentableIn(ForeignLanguage::ObjectiveC, - cast(D))) - break; // Looks ok. - } - if (checkObjectOrOptionalObjectType(TC, D, paramList->get(0))) - Valid = false; + + case ObjCSelectorFamily::Copy: + // Fix-it will replace the "copy" in the selector with "makeCopy". + prefix += "Copy"; break; - case 2: - // (iOS/watchOS only) Two arguments, the second of which is a UIEvent. - // We don't currently enforce the UIEvent part. - if (!isRelaxedIBAction(TC)) { - relaxedIBActionUsedOnOSX = true; - break; - } - if (checkObjectOrOptionalObjectType(TC, D, paramList->get(0))) - Valid = false; - if (checkObjectOrOptionalObjectType(TC, D, paramList->get(1))) - Valid = false; - break; - default: - // No platform allows an action signature with more than two arguments. - TC.diagnose(D, diag::invalid_ibaction_argument_count, - isRelaxedIBAction(TC)); - Valid = false; + + case ObjCSelectorFamily::MutableCopy: + // Fix-it will replace the "mutable" in the selector with "makeMutable". + prefix += "Mutable"; break; } - if (relaxedIBActionUsedOnOSX) { - TC.diagnose(D, diag::invalid_ibaction_argument_count, - /*relaxedIBAction=*/false); - Valid = false; + // Emit the actual error. + TC.diagnose(FD, diag::ibsegueaction_objc_method_family, + attr->getAttrName(), currentSelector); + + // The rest of this is just fix-it generation. + + /// Replaces the first word of \c oldName with the prefix, where "word" is a + /// sequence of lowercase characters. + auto replacingPrefix = [&](Identifier oldName) -> Identifier { + SmallString<32> scratch = prefix; + scratch += oldName.str().drop_while(clang::isLowercase); + return TC.Context.getIdentifier(scratch); + }; + + // Suggest changing the Swift name of the method, unless there is already an + // explicit selector. + if (!FD->getAttrs().hasAttribute() || + !FD->getAttrs().getAttribute()->hasName()) { + auto newSwiftBaseName = replacingPrefix(FD->getBaseName().getIdentifier()); + auto argumentNames = FD->getFullName().getArgumentNames(); + DeclName newSwiftName(TC.Context, newSwiftBaseName, argumentNames); + + auto diag = TC.diagnose(FD, diag::fixit_rename_in_swift, newSwiftName); + fixDeclarationName(diag, FD, newSwiftName); } - if (!Valid) - attr->setInvalid(); + // Suggest changing just the selector to one with a different first piece. + auto oldPieces = currentSelector.getSelectorPieces(); + SmallVector newPieces(oldPieces.begin(), oldPieces.end()); + newPieces[0] = replacingPrefix(newPieces[0]); + ObjCSelector newSelector(TC.Context, currentSelector.getNumArgs(), newPieces); + + auto diag = TC.diagnose(FD, diag::fixit_rename_in_objc, newSelector); + fixDeclarationObjCName(diag, FD, currentSelector, newSelector); } /// Get the innermost enclosing declaration for a declaration. diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp index 318f36c4529..dc607f0e60e 100644 --- a/lib/Sema/TypeCheckDeclObjC.cpp +++ b/lib/Sema/TypeCheckDeclObjC.cpp @@ -35,6 +35,7 @@ bool swift::shouldDiagnoseObjCReason(ObjCReason reason, ASTContext &ctx) { case ObjCReason::ExplicitlyObjC: case ObjCReason::ExplicitlyIBOutlet: case ObjCReason::ExplicitlyIBAction: + case ObjCReason::ExplicitlyIBSegueAction: case ObjCReason::ExplicitlyNSManaged: case ObjCReason::MemberOfObjCProtocol: case ObjCReason::OverridesObjC: @@ -63,6 +64,7 @@ unsigned swift::getObjCDiagnosticAttrKind(ObjCReason reason) { case ObjCReason::ExplicitlyObjC: case ObjCReason::ExplicitlyIBOutlet: case ObjCReason::ExplicitlyIBAction: + case ObjCReason::ExplicitlyIBSegueAction: case ObjCReason::ExplicitlyNSManaged: case ObjCReason::MemberOfObjCProtocol: case ObjCReason::OverridesObjC: @@ -366,6 +368,40 @@ static bool checkObjCInForeignClassContext(const ValueDecl *VD, return true; } +static VersionRange getMinOSVersionForClassStubs(const llvm::Triple &target) { + if (target.isMacOSX()) + return VersionRange::allGTE(llvm::VersionTuple(10, 15, 0)); + if (target.isiOS()) // also returns true on tvOS + return VersionRange::allGTE(llvm::VersionTuple(13, 0, 0)); + if (target.isWatchOS()) + return VersionRange::allGTE(llvm::VersionTuple(6, 0, 0)); + return VersionRange::all(); +} + +static bool checkObjCClassStubAvailability(ASTContext &ctx, const Decl *decl) { + auto minRange = getMinOSVersionForClassStubs(ctx.LangOpts.Target); + + auto targetRange = AvailabilityContext::forDeploymentTarget(ctx); + if (targetRange.getOSVersion().isContainedIn(minRange)) + return true; + + auto declRange = AvailabilityInference::availableRange(decl, ctx); + return declRange.getOSVersion().isContainedIn(minRange); +} + +static const ClassDecl *getResilientAncestor(ModuleDecl *mod, + const ClassDecl *classDecl) { + auto *superclassDecl = classDecl; + + for (;;) { + if (superclassDecl->hasResilientMetadata(mod, + ResilienceExpansion::Maximal)) + return superclassDecl; + + superclassDecl = superclassDecl->getSuperclassDecl(); + } +} + /// Check whether the given declaration occurs within a constrained /// extension, or an extension of a generic class, or an /// extension of an Objective-C runtime visible class, and @@ -386,13 +422,21 @@ static bool checkObjCInExtensionContext(const ValueDecl *value, auto *mod = value->getModuleContext(); auto &ctx = mod->getASTContext(); - if (!ctx.LangOpts.EnableObjCResilientClassStubs) { + if (!checkObjCClassStubAvailability(ctx, value)) { if (classDecl->checkAncestry().contains( AncestryFlags::ResilientOther) || classDecl->hasResilientMetadata(mod, ResilienceExpansion::Maximal)) { if (diagnose) { - value->diagnose(diag::objc_in_resilient_extension); + auto &target = ctx.LangOpts.Target; + auto platform = prettyPlatformString(targetPlatform(ctx.LangOpts)); + auto range = getMinOSVersionForClassStubs(target); + auto *ancestor = getResilientAncestor(mod, classDecl); + value->diagnose(diag::objc_in_resilient_extension, + value->getDescriptiveKind(), + ancestor->getName(), + platform, + range.getLowerEndpoint()); } return true; } @@ -1050,16 +1094,26 @@ static Optional shouldMarkClassAsObjC(const ClassDecl *CD) { } // If the class has resilient ancestry, @objc just controls the runtime - // name unless -enable-resilient-objc-class-stubs is enabled. + // name unless all targets where the class is available support + // class stubs. if (ancestry.contains(AncestryFlags::ResilientOther) && - !ctx.LangOpts.EnableObjCResilientClassStubs) { + !checkObjCClassStubAvailability(ctx, CD)) { if (attr->hasName()) { const_cast(CD)->getAttrs().add( new (ctx) ObjCRuntimeNameAttr(*attr)); return None; } - ctx.Diags.diagnose(attr->getLocation(), diag::objc_for_resilient_class) + + auto &target = ctx.LangOpts.Target; + auto platform = prettyPlatformString(targetPlatform(ctx.LangOpts)); + auto range = getMinOSVersionForClassStubs(target); + auto *ancestor = getResilientAncestor(CD->getParentModule(), CD); + ctx.Diags.diagnose(attr->getLocation(), + diag::objc_for_resilient_class, + ancestor->getName(), + platform, + range.getLowerEndpoint()) .fixItRemove(attr->getRangeWithAt()); } @@ -1085,7 +1139,7 @@ static Optional shouldMarkClassAsObjC(const ClassDecl *CD) { } if (ancestry.contains(AncestryFlags::ResilientOther) && - !ctx.LangOpts.EnableObjCResilientClassStubs) { + !checkObjCClassStubAvailability(ctx, CD)) { return None; } @@ -1173,7 +1227,8 @@ Optional shouldMarkAsObjC(const ValueDecl *VD, bool allowImplicit) { return None; } } - // @IBOutlet, @IBAction, @NSManaged, and @GKInspectable imply @objc. + // @IBOutlet, @IBAction, @IBSegueAction, @NSManaged, and @GKInspectable imply + // @objc. // // @IBInspectable and @GKInspectable imply @objc quietly in Swift 3 // (where they warn on failure) and loudly in Swift 4 (error on failure). @@ -1181,6 +1236,8 @@ Optional shouldMarkAsObjC(const ValueDecl *VD, bool allowImplicit) { return ObjCReason(ObjCReason::ExplicitlyIBOutlet); if (VD->getAttrs().hasAttribute()) return ObjCReason(ObjCReason::ExplicitlyIBAction); + if (VD->getAttrs().hasAttribute()) + return ObjCReason(ObjCReason::ExplicitlyIBSegueAction); if (VD->getAttrs().hasAttribute()) return ObjCReason(ObjCReason::ExplicitlyIBInspectable); if (VD->getAttrs().hasAttribute()) diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index ec8c88ad189..9c010bb64cc 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1247,6 +1247,7 @@ namespace { #define UNINTERESTING_ATTR(CLASS) \ void visit##CLASS##Attr(CLASS##Attr *) {} + // Please keep these alphabetical. UNINTERESTING_ATTR(AccessControl) UNINTERESTING_ATTR(Alignment) UNINTERESTING_ATTR(AlwaysEmitIntoClient) @@ -1264,6 +1265,7 @@ namespace { UNINTERESTING_ATTR(IBDesignable) UNINTERESTING_ATTR(IBInspectable) UNINTERESTING_ATTR(IBOutlet) + UNINTERESTING_ATTR(IBSegueAction) UNINTERESTING_ATTR(Indirect) UNINTERESTING_ATTR(Inline) UNINTERESTING_ATTR(Optimize) diff --git a/lib/Sema/TypeCheckObjC.h b/lib/Sema/TypeCheckObjC.h index aca888dd777..39af513ef8b 100644 --- a/lib/Sema/TypeCheckObjC.h +++ b/lib/Sema/TypeCheckObjC.h @@ -49,6 +49,8 @@ public: ExplicitlyIBOutlet, /// Has an explicit '@IBAction' attribute. ExplicitlyIBAction, + /// Has an explicit '@IBSegueAction' attribute. + ExplicitlyIBSegueAction, /// Has an explicit '@NSManaged' attribute. ExplicitlyNSManaged, /// Is a member of an @objc protocol. diff --git a/stdlib/public/Darwin/Dispatch/Queue.swift b/stdlib/public/Darwin/Dispatch/Queue.swift index 6f4c1514a87..9b38fb92cf2 100644 --- a/stdlib/public/Darwin/Dispatch/Queue.swift +++ b/stdlib/public/Darwin/Dispatch/Queue.swift @@ -94,21 +94,25 @@ extension DispatchQueue { internal func _attr(attr: __OS_dispatch_queue_attr?) -> __OS_dispatch_queue_attr? { if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) { - switch self { - case .inherit: - // DISPATCH_AUTORELEASE_FREQUENCY_INHERIT - return __dispatch_queue_attr_make_with_autorelease_frequency(attr, __dispatch_autorelease_frequency_t(0)) - case .workItem: - // DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM - return __dispatch_queue_attr_make_with_autorelease_frequency(attr, __dispatch_autorelease_frequency_t(1)) - case .never: - // DISPATCH_AUTORELEASE_FREQUENCY_NEVER - return __dispatch_queue_attr_make_with_autorelease_frequency(attr, __dispatch_autorelease_frequency_t(2)) - } + return __dispatch_queue_attr_make_with_autorelease_frequency(attr, self._rawValue) } else { return attr } } + + internal var _rawValue: __dispatch_autorelease_frequency_t { + switch self { + case .inherit: + // DISPATCH_AUTORELEASE_FREQUENCY_INHERIT + return (__dispatch_autorelease_frequency_t(rawValue: 0) as Optional)! + case .workItem: + // DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM + return (__dispatch_autorelease_frequency_t(rawValue: 1) as Optional)! + case .never: + // DISPATCH_AUTORELEASE_FREQUENCY_NEVER + return (__dispatch_autorelease_frequency_t(rawValue: 2) as Optional)! + } + } } public class func concurrentPerform(iterations: Int, execute work: (Int) -> Void) { diff --git a/stdlib/public/Darwin/WatchKit/CMakeLists.txt b/stdlib/public/Darwin/WatchKit/CMakeLists.txt index f4368d2b65f..f1d945ec8f9 100644 --- a/stdlib/public/Darwin/WatchKit/CMakeLists.txt +++ b/stdlib/public/Darwin/WatchKit/CMakeLists.txt @@ -8,9 +8,7 @@ add_swift_target_library(swiftWatchKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" - TARGET_SDKS IOS IOS_SIMULATOR WATCHOS WATCHOS_SIMULATOR - SWIFT_MODULE_DEPENDS_IOS Darwin CoreFoundation CoreGraphics CoreImage CoreLocation Dispatch Foundation MapKit ObjectiveC QuartzCore UIKit # auto-updated - os + TARGET_SDKS WATCHOS WATCHOS_SIMULATOR SWIFT_MODULE_DEPENDS_WATCHOS Darwin CoreFoundation CoreGraphics CoreLocation Dispatch Foundation HomeKit MapKit ObjectiveC SceneKit simd UIKit # auto-updated FRAMEWORK_DEPENDS_WEAK WatchKit SWIFT_COMPILE_FLAGS_WATCHOS -Xfrontend -disable-autolink-framework -Xfrontend CoreText diff --git a/test/FixCode/fixits-apply.swift b/test/FixCode/fixits-apply.swift index c2d7148142f..eee2c6bddbc 100644 --- a/test/FixCode/fixits-apply.swift +++ b/test/FixCode/fixits-apply.swift @@ -246,6 +246,7 @@ protocol NonObjCProtocol {} @IBOutlet private var ibout6: [String: String]! @IBInspectable static private var ibinspect1: IBIssues! @IBAction static func ibact() {} + @IBSegueAction static func ibsegact(_: String, _: IBIssues) -> IBIssues { return self } } @IBDesignable extension SomeProt {} diff --git a/test/FixCode/fixits-apply.swift.result b/test/FixCode/fixits-apply.swift.result index 1e3e4861c03..5cb79ac3b70 100644 --- a/test/FixCode/fixits-apply.swift.result +++ b/test/FixCode/fixits-apply.swift.result @@ -246,6 +246,7 @@ protocol NonObjCProtocol {} @IBOutlet private var ibout6: [String: String]! @IBInspectable static private var ibinspect1: IBIssues! @IBAction static func ibact() {} + @IBSegueAction static func ibsegact(_: String, _: IBIssues) -> IBIssues { return self } } @IBDesignable extension SomeProt {} diff --git a/test/IDE/complete_cache.swift b/test/IDE/complete_cache.swift index 2a21a44f825..0cf4c25c2be 100644 --- a/test/IDE/complete_cache.swift +++ b/test/IDE/complete_cache.swift @@ -1,13 +1,13 @@ -// RUN: rm -rf %t.ccp %t.ccp.bak +// RUN: rm -rf %t.ccp %t.ccp.bak %t.mcp -// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_UNQUAL_1 -completion-cache-path=%t.ccp > %t.ccp1.compl.txt +// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_UNQUAL_1 -completion-cache-path=%t.ccp -module-cache-path %t.mcp > %t.ccp1.compl.txt // RUN: cp -r %t.ccp %t.ccp.bak // RUN: %FileCheck %s -check-prefix=CLANG_CTYPES < %t.ccp1.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_MACROS < %t.ccp1.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_DARWIN < %t.ccp1.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_DARWIN_NEG < %t.ccp1.compl.txt -// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_UNQUAL_1 -completion-cache-path=%t.ccp > %t.ccp2.compl.txt +// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_UNQUAL_1 -completion-cache-path=%t.ccp -module-cache-path %t.mcp > %t.ccp2.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_CTYPES < %t.ccp2.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_MACROS < %t.ccp2.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_DARWIN < %t.ccp2.compl.txt @@ -24,7 +24,7 @@ // Qualified. -// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_MACROS_1 -completion-cache-path=%t.ccp > %t.macros.ccp1.compl.txt +// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_MACROS_1 -completion-cache-path=%t.ccp -module-cache-path %t.mcp > %t.macros.ccp1.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_QUAL_MACROS_1 -check-prefix=CLANG_QUAL_MACROS_1-%target-runtime < %t.macros.ccp1.compl.txt // RUN: diff -r -u %t.ccp %t.ccp.bak @@ -33,14 +33,14 @@ // Qualified with dot. -// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_MACROS_2 -completion-cache-path=%t.ccp > %t.macros2.ccp1.compl.txt +// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_MACROS_2 -completion-cache-path=%t.ccp -module-cache-path %t.mcp > %t.macros2.ccp1.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_QUAL_MACROS_2 -check-prefix=CLANG_QUAL_MACROS_2-%target-runtime < %t.macros2.ccp1.compl.txt // Check the individual cache item. // RUN: %target-swift-ide-test -dump-completion-cache %t.ccp/macros-dot-* | %FileCheck %s -check-prefix=CLANG_QUAL_MACROS_2 // Qualified private with dot. -// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_STRING -completion-cache-path=%t.ccp > %t.string.ccp1.compl.txt +// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=CLANG_QUAL_STRING -completion-cache-path=%t.ccp -module-cache-path %t.mcp > %t.string.ccp1.compl.txt // RUN: %FileCheck %s -check-prefix=CLANG_QUAL_STRING < %t.string.ccp1.compl.txt diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift index 5636a674c93..d3bdd5d7db4 100644 --- a/test/IDE/complete_decl_attribute.swift +++ b/test/IDE/complete_decl_attribute.swift @@ -57,6 +57,7 @@ func method(){} // KEYWORD2-NEXT: Keyword/None: warn_unqualified_access[#Func Attribute#]; name=warn_unqualified_access{{$}} // KEYWORD2-NEXT: Keyword/None: usableFromInline[#Func Attribute#]; name=usableFromInline // KEYWORD2-NEXT: Keyword/None: discardableResult[#Func Attribute#]; name=discardableResult +// KEYWORD2-NEXT: Keyword/None: IBSegueAction[#Func Attribute#]; name=IBSegueAction{{$}} // KEYWORD2-NEXT: End completions @#^KEYWORD3^# @@ -165,6 +166,7 @@ struct _S { // ON_METHOD-DAG: Keyword/None: warn_unqualified_access[#Func Attribute#]; name=warn_unqualified_access // ON_METHOD-DAG: Keyword/None: usableFromInline[#Func Attribute#]; name=usableFromInline // ON_METHOD-DAG: Keyword/None: discardableResult[#Func Attribute#]; name=discardableResult +// ON_METHOD-DAG: Keyword/None: IBSegueAction[#Func Attribute#]; name=IBSegueAction // ON_METHOD: End completions @#^ON_MEMBER_LAST^# @@ -190,6 +192,7 @@ struct _S { // ON_MEMBER_LAST-DAG: Keyword/None: usableFromInline[#Declaration Attribute#]; name=usableFromInline // ON_MEMBER_LAST-DAG: Keyword/None: discardableResult[#Declaration Attribute#]; name=discardableResult // ON_MEMBER_LAST-DAG: Keyword/None: GKInspectable[#Declaration Attribute#]; name=GKInspectable +// ON_MEMBER_LAST-DAG: Keyword/None: IBSegueAction[#Declaration Attribute#]; name=IBSegueAction // ON_MEMBER_LAST-DAG: Keyword/None: _propertyWrapper[#Declaration Attribute#]; name=_propertyWrapper // ON_MEMBER_LAST-NOT: Keyword // ON_MEMBER_LAST: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct @@ -222,6 +225,6 @@ struct _S { // KEYWORD_LAST-NEXT: Keyword/None: discardableResult[#Declaration Attribute#]; name=discardableResult // KEYWORD_LAST-NEXT: Keyword/None: GKInspectable[#Declaration Attribute#]; name=GKInspectable{{$}} // KEYWORD_LAST-NEXT: Keyword/None: _propertyWrapper[#Declaration Attribute#]; name=_propertyWrapper -// KEYWORD_LAST-NOT: Keyword +// KEYWORD_LAST-NEXT: Keyword/None: IBSegueAction[#Declaration Attribute#]; name=IBSegueAction{{$}} // KEYWORD_LAST: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // KEYWORD_LAST: End completions diff --git a/test/IDE/print_ast_tc_decls.swift b/test/IDE/print_ast_tc_decls.swift index aa5ef08c4ef..31033c0b8b0 100644 --- a/test/IDE/print_ast_tc_decls.swift +++ b/test/IDE/print_ast_tc_decls.swift @@ -538,6 +538,9 @@ class d0170_TestAvailability { @IBAction func anAction(_: AnyObject) {} // PASS_COMMON-NEXT: {{^}} @objc @IBAction func anAction(_: AnyObject){{$}} + @IBSegueAction func aSegueAction(_ coder: AnyObject, sender: AnyObject, identifier: AnyObject?) -> Any? { fatalError() } +// PASS_COMMON-NEXT: {{^}} @objc @IBSegueAction func aSegueAction(_ coder: AnyObject, sender: AnyObject, identifier: AnyObject?) -> Any?{{$}} + @IBDesignable class ADesignableClass {} // PASS_COMMON-NEXT: {{^}} @IBDesignable class ADesignableClass {{{$}} diff --git a/test/IRGen/class_update_callback_with_stub.swift b/test/IRGen/class_update_callback_with_stub.swift index 480ce50a1cb..f22bd47f093 100644 --- a/test/IRGen/class_update_callback_with_stub.swift +++ b/test/IRGen/class_update_callback_with_stub.swift @@ -3,7 +3,7 @@ // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -I %t %S/../Inputs/resilient_struct.swift // RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -emit-module-path %t/resilient_class.swiftmodule -enable-library-evolution %S/../Inputs/resilient_class.swift // RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -emit-module-path %t/resilient_objc_class.swiftmodule -enable-library-evolution %S/../Inputs/resilient_objc_class.swift -// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -I %t -emit-ir -enable-library-evolution -enable-resilient-objc-class-stubs %s > %t/out +// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -I %t -emit-ir -enable-library-evolution -target %target-next-stable-abi-triple %s > %t/out // RUN: %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-runtime -DINT=i%target-ptrsize < %t/out // RUN: %FileCheck %s --check-prefix=NEGATIVE < %t/out @@ -12,6 +12,7 @@ import resilient_class import resilient_objc_class // REQUIRES: objc_interop +// REQUIRES: swift_stable_abi // -- Nominal type descriptor for ResilientSubclass // the interesting part is the 'extra class flags' field has a value of 1. diff --git a/test/IRGen/objc_methods.swift b/test/IRGen/objc_methods.swift index cef0ce11137..a6e2d694bc8 100644 --- a/test/IRGen/objc_methods.swift +++ b/test/IRGen/objc_methods.swift @@ -23,6 +23,7 @@ class Foo: Fooable { func bar() {} @objc func baz() {} @IBAction func garply(_: AnyObject?) {} + @IBSegueAction func harply(_: AnyObject?, _: AnyObject) -> AnyObject? {fatalError()} @objc func block(_: (Int) -> Int) {} @objc func block2(_: (Int,Int) -> Int) {} @@ -44,14 +45,15 @@ class ObjcDestructible: NSObject { // CHECK: [[NO_ARGS_SIGNATURE:@.*]] = private unnamed_addr constant [8 x i8] c"v16@0:8\00" // CHECK: [[GARPLY_SIGNATURE:@.*]] = private unnamed_addr constant [11 x i8] c"v24@0:8@16\00" +// CHECK: [[HARPLY_SIGNATURE:@.*]] = private unnamed_addr constant [14 x i8] c"@32@0:8@16@24\00" // CHECK: [[BLOCK_SIGNATURE_TRAD:@.*]] = private unnamed_addr constant [12 x i8] c"v24@0:8@?16\00" // CHECK-macosx: [[FAIL_SIGNATURE:@.*]] = private unnamed_addr constant [12 x i8] c"c24@0:8^@16\00" // CHECK-ios: [[FAIL_SIGNATURE:@.*]] = private unnamed_addr constant [12 x i8] c"B24@0:8^@16\00" // CHECK-tvos: [[FAIL_SIGNATURE:@.*]] = private unnamed_addr constant [12 x i8] c"B24@0:8^@16\00" // CHECK: @_INSTANCE_METHODS__TtC12objc_methods3Foo = private constant { {{.*}}] } { // CHECK: i32 24, -// CHECK: i32 9, -// CHECK: [9 x { i8*, i8*, i8* }] [{ +// CHECK: i32 10, +// CHECK: [10 x { i8*, i8*, i8* }] [{ // CHECK: i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"\01L_selector_data(baz)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[NO_ARGS_SIGNATURE]], i64 0, i64 0), // CHECK: i8* bitcast (void (i8*, i8*)* @"$s12objc_methods3FooC3bazyyFTo" to i8*) @@ -60,6 +62,10 @@ class ObjcDestructible: NSObject { // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[GARPLY_SIGNATURE]], i64 0, i64 0), // CHECK: i8* bitcast (void (i8*, i8*, i8*)* @"$s12objc_methods3FooC6garplyyyyXlSgFTo" to i8*) // CHECK: }, { +// CHECK: i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01L_selector_data(harply::)", i64 0, i64 0), +// CHECK: i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[HARPLY_SIGNATURE]], i64 0, i64 0), +// CHECK: i8* bitcast (i8* (i8*, i8*, i8*, i8*)* @"$s12objc_methods3FooC6harplyyyXlSgAE_yXltFTo" to i8*) +// CHECK: }, { // CHECK: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(block:)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([12 x i8], [12 x i8]* [[BLOCK_SIGNATURE_TRAD]], i64 0, i64 0), // CHECK: i8* bitcast (void (i8*, i8*, i64 (i64)*)* @"$s12objc_methods3FooC5blockyyS2iXEFTo" to i8*) diff --git a/test/IRGen/opaque_result_type_availability.swift b/test/IRGen/opaque_result_type_availability.swift index 972bd434699..b5fdfb74cfb 100644 --- a/test/IRGen/opaque_result_type_availability.swift +++ b/test/IRGen/opaque_result_type_availability.swift @@ -1,12 +1,11 @@ // RUN: %target-swift-frontend -target x86_64-apple-macosx10.9 -Onone -emit-ir %s | %FileCheck --check-prefix=MAYBE-AVAILABLE %s -// TODO: Build with a macos deployment target that unconditionally supports opaque result types -// R/UN: %target-swift-frontend -target x86_64-apple-macosx10.9999 -Onone -emit-ir %s | %FileCheck --check-prefix=ALWAYS-AVAILABLE %s +// RUN: %target-swift-frontend -target x86_64-apple-macosx10.15 -Onone -emit-ir %s | %FileCheck --check-prefix=ALWAYS-AVAILABLE %s // REQUIRES: OS=macosx protocol P {} extension Int: P {} -@available(macOS 9999, *) +@available(macOS 10.15, *) func foo() -> some P { return 1738 } @@ -14,7 +13,7 @@ func foo() -> some P { @_silgen_name("external") func generic(x: T, y: T) -@available(macOS 9999, *) +@available(macOS 10.15, *) public func main() { generic(x: foo(), y: foo()) } diff --git a/test/Index/kinds_objc.swift b/test/Index/kinds_objc.swift index 1abc2a36181..a64d6a15b7b 100644 --- a/test/Index/kinds_objc.swift +++ b/test/Index/kinds_objc.swift @@ -3,12 +3,17 @@ @objc class TargetForIBAction {} // CHECK: [[@LINE-1]]:13 | class/Swift | TargetForIBAction | [[TargetForIBAction_USR:.*]] | Def | +@objc class TargetForIBSegueAction {} +// CHECK: [[@LINE-1]]:13 | class/Swift | TargetForIBSegueAction | [[TargetForIBSegueAction_USR:.*]] | Def | class AttrAnnots { @IBOutlet var iboutletString: AnyObject? // CHECK: [[@LINE-1]]:17 | instance-property(IB)/Swift | iboutletString | @IBAction func someibaction(o: TargetForIBAction) {} // CHECK: [[@LINE-1]]:18 | instance-method(IB)/Swift | someibaction(o:) | {{.*}} | Def,Dyn,RelChild,RelIBType | rel: 2 // CHECK-NEXT: RelIBType | class/Swift | TargetForIBAction | [[TargetForIBAction_USR]] + @IBSegueAction func someibsegue(coder: Any, o: TargetForIBSegueAction) -> Any {} + // CHECK: [[@LINE-1]]:23 | instance-method(IB)/Swift | someibsegue(coder:o:) | {{.*}} | Def,Dyn,RelChild,RelIBType | rel: 2 + // CHECK-NEXT: RelIBType | class/Swift | TargetForIBSegueAction | [[TargetForIBSegueAction_USR]] @GKInspectable var gkString = "gk" // CHECK: [[@LINE-1]]:22 | instance-property(GKI)/Swift | gkString | } diff --git a/test/Interpreter/objc_class_resilience_stubs.swift b/test/Interpreter/objc_class_resilience_stubs.swift index 595551ba7aa..f84c042523a 100644 --- a/test/Interpreter/objc_class_resilience_stubs.swift +++ b/test/Interpreter/objc_class_resilience_stubs.swift @@ -6,13 +6,14 @@ // RUN: %target-build-swift-dylib(%t/%target-library-name(resilient_objc_class)) -I %t -L %t -lresilient_struct -enable-library-evolution %S/../Inputs/resilient_objc_class.swift -emit-module -emit-module-path %t/resilient_objc_class.swiftmodule // RUN: %target-codesign %t/%target-library-name(resilient_objc_class) -// RUN: %target-build-swift %s -L %t -I %t -lresilient_struct -lresilient_objc_class -o %t/main %target-rpath(%t) -Xfrontend -enable-resilient-objc-class-stubs +// RUN: %target-build-swift %s -L %t -I %t -lresilient_struct -lresilient_objc_class -o %t/main %target-rpath(%t) -target %target-next-stable-abi-triple // RUN: %target-codesign %t/main // RUN: %target-run %t/main %t/%target-library-name(resilient_struct) %t/%target-library-name(resilient_objc_class) // REQUIRES: executable_test // REQUIRES: objc_interop +// REQUIRES: swift_stable_abi import StdlibUnittest import Foundation diff --git a/test/Parse/availability_query.swift b/test/Parse/availability_query.swift index 96a87cfa7c7..eea8399c4ff 100644 --- a/test/Parse/availability_query.swift +++ b/test/Parse/availability_query.swift @@ -39,10 +39,11 @@ if #available(OSX) { // expected-error {{expected version number}} if #available(OSX 10.51 { // expected-error {{expected ')'}} expected-note {{to match this opening '('}} expected-error {{must handle potential future platforms with '*'}} {{24-24=, *}} } -if #available(iDishwasherOS 10.51) { // expected-error {{unrecognized platform name 'iDishwasherOS'}} +if #available(iDishwasherOS 10.51) { // expected-warning {{unrecognized platform name 'iDishwasherOS'}} +// expected-error@-1 {{must handle potential future platforms with '*'}} } -if #available(iDishwasherOS 10.51, *) { // expected-error {{unrecognized platform name 'iDishwasherOS'}} +if #available(iDishwasherOS 10.51, *) { // expected-warning {{unrecognized platform name 'iDishwasherOS'}} } if #available(OSX 10.51, OSX 10.52, *) { // expected-error {{version for 'OSX' already specified}} @@ -79,10 +80,12 @@ if #available(OSX 10.51,) { // expected-error {{expected platform name}} if #available(OSX 10.51, iOS { // expected-error {{expected version number}} // expected-error {{expected ')'}} expected-note {{to match this opening '('}} } -if #available(OSX 10.51, iOS 8.0, iDishwasherOS 10.51) { // expected-error {{unrecognized platform name 'iDishwasherOS'}} +if #available(OSX 10.51, iOS 8.0, iDishwasherOS 10.51) { // expected-warning {{unrecognized platform name 'iDishwasherOS'}} +// expected-error@-1 {{must handle potential future platforms with '*'}} } -if #available(iDishwasherOS 10.51, OSX 10.51) { // expected-error {{unrecognized platform name 'iDishwasherOS'}} +if #available(iDishwasherOS 10.51, OSX 10.51) { // expected-warning {{unrecognized platform name 'iDishwasherOS'}} +// expected-error@-1 {{must handle potential future platforms with '*'}} } if #available(OSX 10.51 || iOS 8.0) {// expected-error {{'||' cannot be used in an availability condition}} diff --git a/test/PrintAsObjC/classes.swift b/test/PrintAsObjC/classes.swift index c031d760f53..9d46ef4a1dd 100644 --- a/test/PrintAsObjC/classes.swift +++ b/test/PrintAsObjC/classes.swift @@ -223,6 +223,7 @@ class NotObjC {} // CHECK-NEXT: - (void)testDictionaryBridging3:(NSDictionary * _Nonnull)a; // CHECK-NEXT: - (void)testSetBridging:(NSSet * _Nonnull)a; // CHECK-NEXT: - (IBAction)actionMethod:(id _Nonnull)_; +// CHECK-NEXT: - (IBSegueAction NSObject * _Nonnull)segueActionMethod:(NSCoder * _Nonnull)coder sender:(id _Nonnull)sender SWIFT_WARN_UNUSED_RESULT; // CHECK-NEXT: - (void)methodWithReservedParameterNames:(id _Nonnull)long_ protected:(id _Nonnull)protected_; // CHECK-NEXT: - (void)honorRenames:(CustomName * _Nonnull)_; // CHECK-NEXT: - (Methods * _Nullable __unsafe_unretained)unmanaged:(id _Nonnull __unsafe_unretained)_ SWIFT_WARN_UNUSED_RESULT; @@ -280,6 +281,7 @@ class NotObjC {} @objc func testSetBridging(_ a: Set) {} @IBAction func actionMethod(_: AnyObject) {} + @IBSegueAction func segueActionMethod(_ coder: NSCoder, sender: Any) -> NSObject { fatalError() } @objc func methodWithReservedParameterNames(_ long: AnyObject, protected: AnyObject) {} diff --git a/test/PrintAsObjC/resilient-ancestry-stable-abi.swift b/test/PrintAsObjC/resilient-ancestry-stable-abi.swift index f572deea7db..bfa2a08230a 100644 --- a/test/PrintAsObjC/resilient-ancestry-stable-abi.swift +++ b/test/PrintAsObjC/resilient-ancestry-stable-abi.swift @@ -4,7 +4,7 @@ // RUN: cp %S/Inputs/custom-modules/module.map %t/module.map -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %S/resilient-ancestry.swift -module-name resilient -emit-objc-header-path %t/resilient.h -I %t -enable-library-evolution -enable-resilient-objc-class-stubs +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %S/resilient-ancestry.swift -module-name resilient -emit-objc-header-path %t/resilient.h -I %t -enable-library-evolution -target %target-next-stable-abi-triple // RUN: %FileCheck %S/resilient-ancestry.swift < %t/resilient.h // RUN: %check-in-clang %t/resilient.h -I %t diff --git a/test/SourceKit/CodeFormat/indent-ibaction.swift b/test/SourceKit/CodeFormat/indent-ibaction.swift index 4c13bea2226..78c47fc6d25 100644 --- a/test/SourceKit/CodeFormat/indent-ibaction.swift +++ b/test/SourceKit/CodeFormat/indent-ibaction.swift @@ -1,8 +1,13 @@ @IBAction func foo() { var xyz : Int } +@IBSegueAction func bar() { + var xyz : Int +} -// RUN: %sourcekitd-test -req=format -line=2 -length=1 %s >%t.response -// RUN: %FileCheck --strict-whitespace %s <%t.response +// RUN: %sourcekitd-test -req=format -line=2 -length=1 %s >%t.action.response +// RUN: %FileCheck --strict-whitespace %s <%t.action.response +// RUN: %sourcekitd-test -req=format -line=5 -length=1 %s >%t.segueaction.response +// RUN: %FileCheck --strict-whitespace %s <%t.segueaction.response // CHECK: key.sourcetext: " var xyz : Int" diff --git a/test/SourceKit/DocumentStructure/Inputs/main.swift b/test/SourceKit/DocumentStructure/Inputs/main.swift index f5e31b1f989..1825f3a070c 100644 --- a/test/SourceKit/DocumentStructure/Inputs/main.swift +++ b/test/SourceKit/DocumentStructure/Inputs/main.swift @@ -129,3 +129,9 @@ enum MySecondEnum { } func someFunc(input :Int?, completion: () throws -> Void) rethrows {} + +class OneMore { + @IBSegueAction func testAction(coder: AnyObject, _ ident: String) -> AnyObject { + fatalError() + } +} diff --git a/test/SourceKit/DocumentStructure/structure.swift.empty.response b/test/SourceKit/DocumentStructure/structure.swift.empty.response index 330079849eb..91c8d8f9b44 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.empty.response +++ b/test/SourceKit/DocumentStructure/structure.swift.empty.response @@ -1,6 +1,6 @@ { key.offset: 0, - key.length: 2136, + key.length: 2259, key.diagnostic_stage: source.diagnostic.stage.swift.parse, key.substructure: [ { @@ -1326,6 +1326,70 @@ key.namelength: 10 } ] + }, + { + key.kind: source.lang.swift.decl.class, + key.accessibility: source.lang.swift.accessibility.internal, + key.name: "OneMore", + key.offset: 2137, + key.length: 121, + key.runtime_name: "_TtC4main7OneMore", + key.nameoffset: 2143, + key.namelength: 7, + key.bodyoffset: 2152, + key.bodylength: 105, + key.substructure: [ + { + key.kind: source.lang.swift.decl.function.method.instance, + key.accessibility: source.lang.swift.accessibility.internal, + key.name: "testAction(coder:_:)", + key.offset: 2170, + key.length: 86, + key.typename: "AnyObject", + key.selector_name: "testActionWithCoder::", + key.nameoffset: 2175, + key.namelength: 45, + key.bodyoffset: 2235, + key.bodylength: 20, + key.attributes: [ + { + key.offset: 2155, + key.length: 14, + key.attribute: source.decl.attribute.ibsegueaction + } + ], + key.substructure: [ + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "coder", + key.offset: 2186, + key.length: 16, + key.typename: "AnyObject", + key.nameoffset: 2186, + key.namelength: 5 + }, + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "ident", + key.offset: 2204, + key.length: 15, + key.typename: "String", + key.nameoffset: 0, + key.namelength: 0 + }, + { + key.kind: source.lang.swift.expr.call, + key.name: "fatalError", + key.offset: 2240, + key.length: 12, + key.nameoffset: 2240, + key.namelength: 10, + key.bodyoffset: 2251, + key.bodylength: 0 + } + ] + } + ] } ], key.diagnostics: [ diff --git a/test/SourceKit/DocumentStructure/structure.swift.foobar.response b/test/SourceKit/DocumentStructure/structure.swift.foobar.response index aea96507edf..e09c97690fa 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.foobar.response +++ b/test/SourceKit/DocumentStructure/structure.swift.foobar.response @@ -1,6 +1,6 @@ { key.offset: 0, - key.length: 2136, + key.length: 2259, key.diagnostic_stage: source.diagnostic.stage.swift.parse, key.substructure: [ { @@ -1326,6 +1326,70 @@ key.namelength: 10 } ] + }, + { + key.kind: source.lang.swift.decl.class, + key.accessibility: source.lang.swift.accessibility.internal, + key.name: "OneMore", + key.offset: 2137, + key.length: 121, + key.runtime_name: "_TtC4main7OneMore", + key.nameoffset: 2143, + key.namelength: 7, + key.bodyoffset: 2152, + key.bodylength: 105, + key.substructure: [ + { + key.kind: source.lang.swift.decl.function.method.instance, + key.accessibility: source.lang.swift.accessibility.internal, + key.name: "testAction(coder:_:)", + key.offset: 2170, + key.length: 86, + key.typename: "AnyObject", + key.selector_name: "testActionWithCoder::", + key.nameoffset: 2175, + key.namelength: 45, + key.bodyoffset: 2235, + key.bodylength: 20, + key.attributes: [ + { + key.offset: 2155, + key.length: 14, + key.attribute: source.decl.attribute.ibsegueaction + } + ], + key.substructure: [ + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "coder", + key.offset: 2186, + key.length: 16, + key.typename: "AnyObject", + key.nameoffset: 2186, + key.namelength: 5 + }, + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "ident", + key.offset: 2204, + key.length: 15, + key.typename: "String", + key.nameoffset: 0, + key.namelength: 0 + }, + { + key.kind: source.lang.swift.expr.call, + key.name: "fatalError", + key.offset: 2240, + key.length: 12, + key.nameoffset: 2240, + key.namelength: 10, + key.bodyoffset: 2251, + key.bodylength: 0 + } + ] + } + ] } ], key.diagnostics: [ diff --git a/test/SourceKit/DocumentStructure/structure.swift.response b/test/SourceKit/DocumentStructure/structure.swift.response index 82b8c122b86..d4e91a12c91 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.response +++ b/test/SourceKit/DocumentStructure/structure.swift.response @@ -1,6 +1,6 @@ { key.offset: 0, - key.length: 2136, + key.length: 2259, key.diagnostic_stage: source.diagnostic.stage.swift.parse, key.substructure: [ { @@ -1326,6 +1326,70 @@ key.namelength: 10 } ] + }, + { + key.kind: source.lang.swift.decl.class, + key.accessibility: source.lang.swift.accessibility.internal, + key.name: "OneMore", + key.offset: 2137, + key.length: 121, + key.runtime_name: "_TtC13StructureTest7OneMore", + key.nameoffset: 2143, + key.namelength: 7, + key.bodyoffset: 2152, + key.bodylength: 105, + key.substructure: [ + { + key.kind: source.lang.swift.decl.function.method.instance, + key.accessibility: source.lang.swift.accessibility.internal, + key.name: "testAction(coder:_:)", + key.offset: 2170, + key.length: 86, + key.typename: "AnyObject", + key.selector_name: "testActionWithCoder::", + key.nameoffset: 2175, + key.namelength: 45, + key.bodyoffset: 2235, + key.bodylength: 20, + key.attributes: [ + { + key.offset: 2155, + key.length: 14, + key.attribute: source.decl.attribute.ibsegueaction + } + ], + key.substructure: [ + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "coder", + key.offset: 2186, + key.length: 16, + key.typename: "AnyObject", + key.nameoffset: 2186, + key.namelength: 5 + }, + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "ident", + key.offset: 2204, + key.length: 15, + key.typename: "String", + key.nameoffset: 0, + key.namelength: 0 + }, + { + key.kind: source.lang.swift.expr.call, + key.name: "fatalError", + key.offset: 2240, + key.length: 12, + key.nameoffset: 2240, + key.namelength: 10, + key.bodyoffset: 2251, + key.bodylength: 0 + } + ] + } + ] } ], key.diagnostics: [ diff --git a/test/attr/attr_availability.swift b/test/attr/attr_availability.swift index 22c7fbae550..571fba385dd 100644 --- a/test/attr/attr_availability.swift +++ b/test/attr/attr_availability.swift @@ -215,6 +215,24 @@ func shortFormMissingParen() { // expected-error {{expected ')' in 'available' a func shortFormMissingPlatform() { } +@available(iOS 8.0, iDishwasherOS 22.0, *) // expected-warning {{unrecognized platform name 'iDishwasherOS'}} +func shortFormWithUnrecognizedPlatform() { +} + +@available(iOS 8.0, iDishwasherOS 22.0, iRefrigeratorOS 18.0, *) +// expected-warning@-1 {{unrecognized platform name 'iDishwasherOS'}} +// expected-warning@-2 {{unrecognized platform name 'iRefrigeratorOS'}} +func shortFormWithTwoUnrecognizedPlatforms() { +} + +// Make sure that even after the parser hits an unrecognized +// platform it validates the availability. +@available(iOS 8.0, iDishwasherOS 22.0, iOS 9.0, *) +// expected-warning@-1 {{unrecognized platform name 'iDishwasherOS'}} +// expected-error@-2 {{version for 'iOS' already specified}} +func shortFormWithUnrecognizedPlatformContinueValidating() { +} + @available(iOS 8.0, * func shortFormMissingParenAfterWildcard() { // expected-error {{expected ')' in 'available' attribute}} } diff --git a/test/attr/attr_ibaction.swift b/test/attr/attr_ibaction.swift index b0d16514fc3..78409a6215f 100644 --- a/test/attr/attr_ibaction.swift +++ b/test/attr/attr_ibaction.swift @@ -30,7 +30,7 @@ class IBActionWrapperTy { var value : Void = () @IBAction - func process(x: AnyObject) -> Int {} // expected-error {{methods declared @IBAction must return 'Void' (not 'Int')}} + func process(x: AnyObject) -> Int {} // expected-error {{methods declared @IBAction must not return a value}} // @IBAction does /not/ semantically imply @objc. @IBAction // expected-note {{attribute already specified here}} @@ -55,6 +55,14 @@ protocol CP2 : class { } @objc protocol OP1 { } @objc protocol OP2 { } +// Teach the compiler that String is @objc-friendly without importing +// Foundation. +extension String: _ObjectiveCBridgeable { + @_semantics("convertToObjectiveC") public func _bridgeToObjectiveC() -> AnyObject { fatalError() } + public static func _forceBridgeFromObjectiveC(_ x: AnyObject, result: inout String?) { fatalError() } + public static func _conditionallyBridgeFromObjectiveC(_ x: AnyObject, result: inout String?) -> Bool { fatalError() } + @_effects(readonly) public static func _unconditionallyBridgeFromObjectiveC(_ source: AnyObject? ) -> String { fatalError() } +} // Check which argument types @IBAction can take. @objc class X { @@ -74,39 +82,47 @@ protocol CP2 : class { } @IBAction func action6a(_: Any!) {} // Protocol types - @IBAction func action7(_: P1) {} // expected-error{{argument to @IBAction method cannot have non-object type 'P1'}} - @IBAction func action8(_: CP1) {} // expected-error{{argument to @IBAction method cannot have non-object type 'CP1'}} + @IBAction func action7(_: P1) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'P1' cannot be represented in Objective-C}} + @IBAction func action8(_: CP1) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'CP1' cannot be represented in Objective-C}} @IBAction func action9(_: OP1) {} - @IBAction func action10(_: P1?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action11(_: CP1?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} + @IBAction func action10(_: P1?) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action11(_: CP1?) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} @IBAction func action12(_: OP1?) {} - @IBAction func action13(_: P1!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action14(_: CP1!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} + @IBAction func action13(_: P1!) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action14(_: CP1!) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} @IBAction func action15(_: OP1!) {} // Class metatype - @IBAction func action15b(_: X.Type) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action16(_: X.Type?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action17(_: X.Type!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} + @IBAction func action15b(_: X.Type) {} + @IBAction func action16(_: X.Type?) {} + @IBAction func action17(_: X.Type!) {} // AnyClass - @IBAction func action18(_: AnyClass) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action19(_: AnyClass?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action20(_: AnyClass!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} + @IBAction func action18(_: AnyClass) {} + @IBAction func action19(_: AnyClass?) {} + @IBAction func action20(_: AnyClass!) {} // Protocol types - @IBAction func action21(_: P1.Type) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action22(_: CP1.Type) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action23(_: OP1.Type) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action24(_: P1.Type?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action25(_: CP1.Type?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action26(_: OP1.Type?) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action27(_: P1.Type!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action28(_: CP1.Type!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action29(_: OP1.Type!) {} // expected-error{{argument to @IBAction method cannot have non-object type}} + @IBAction func action21(_: P1.Type) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action22(_: CP1.Type) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action23(_: OP1.Type) {} + @IBAction func action24(_: P1.Type?) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action25(_: CP1.Type?) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action26(_: OP1.Type?) {} + @IBAction func action27(_: P1.Type!) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action28(_: CP1.Type!) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + @IBAction func action29(_: OP1.Type!) {} + + // Structs representable in Objective-C + @IBAction func action32(_: Int) {} + @IBAction func action33(_: Int?) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} + + @IBAction func action34(_: String) {} + @IBAction func action35(_: String?) {} // Other bad cases - @IBAction func action30(_: S) {} // expected-error{{argument to @IBAction method cannot have non-object type}} - @IBAction func action31(_: E) {} // expected-error{{argument to @IBAction method cannot have non-object type}} + @IBAction func action30(_: S) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} expected-note{{Swift structs cannot be represented in Objective-C}} + @IBAction func action31(_: E) {} // expected-error{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} expected-note{{non-'@objc' enums cannot be represented in Objective-C}} + init() { } } diff --git a/test/attr/attr_ibaction_ios.swift b/test/attr/attr_ibaction_ios.swift index 53b44185d2f..47546317e56 100644 --- a/test/attr/attr_ibaction_ios.swift +++ b/test/attr/attr_ibaction_ios.swift @@ -1,78 +1,29 @@ -// RUN: not %target-build-swift -typecheck %s 2>&1 | %FileCheck -check-prefix=CHECK-%target-os -check-prefix=CHECK-BOTH %s +// RUN: not %target-build-swift -typecheck %s 2>&1 | %FileCheck -check-prefix=CHECK-%target-os %s +// REQUIRES: objc_interop // REQUIRES: executable_test -struct IntWrapper { - let value: Int -} - class IBActionWrapperTy { @IBAction func nullary() {} // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-1]] - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have a single argument - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-3]] - - @IBAction func reqReq(_: AnyObject, _: AnyObject) {} - @IBAction func reqOpt(_: AnyObject, _: AnyObject?) {} - @IBAction func reqImp(_: AnyObject, _: AnyObject!) {} - @IBAction func optReq(_: AnyObject?, _: AnyObject) {} - @IBAction func optOpt(_: AnyObject?, _: AnyObject?) {} - @IBAction func optImp(_: AnyObject?, _: AnyObject!) {} - @IBAction func impReq(_: AnyObject!, _: AnyObject) {} - @IBAction func impOpt(_: AnyObject!, _: AnyObject?) {} - @IBAction func impImp(_: AnyObject!, _: AnyObject!) {} - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-9]] - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-18]]:18: error: @IBAction methods must have a single argument - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] - // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-27]] + // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have 1 argument + // CHECK-tvos-NOT: attr_ibaction_ios.swift:[[@LINE-3]] + // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-4]] - @IBAction func reqBad(_: AnyObject, _: IBActionWrapperTy) {} - // CHECK-ios: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: argument to @IBAction method cannot have non-'@objc' class type - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have a single argument - // CHECK-watch: attr_ibaction_ios.swift:[[@LINE-3]]:18: error: argument to @IBAction method cannot have non-'@objc' class type - - @IBAction func badReq(_: Int, _: AnyObject) {} - // CHECK-ios: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: argument to @IBAction method cannot have non-object type - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have a single argument - - @IBAction func badBad(_: Int, _: IBActionWrapperTy) {} - // CHECK-ios: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: argument to @IBAction method cannot have non-object type - // CHECK-ios: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: argument to @IBAction method cannot have non-'@objc' class type - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-3]]:18: error: @IBAction methods must have a single argument - - @IBAction func tooManyArgs(_: AnyObject, _: AnyObject, _: AnyObject) {} - // CHECK-ios: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: @IBAction methods can only have up to 2 arguments - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have a single argument - - @IBAction func watchKitLike(_: Int) {} + @IBAction func unary(_: AnyObject) {} // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-1]] - // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: argument to @IBAction method cannot have non-object type + // CHECK-macosx-NOT: attr_ibaction_ios.swift:[[@LINE-2]] + // CHECK-tvos-NOT: attr_ibaction_ios.swift:[[@LINE-3]] + // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-4]] - @IBAction func watchKitLikeBad(_: IntWrapper) {} - // CHECK-BOTH: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: argument to @IBAction method cannot have non-object type + @IBAction func binary(_: AnyObject, _: AnyObject) {} + // CHECK-ios-NOT: attr_ibaction_ios.swift:[[@LINE-1]] + // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have 1 argument + // CHECK-tvos-NOT: attr_ibaction_ios.swift:[[@LINE-3]] + // CHECK-watchos-NOT: attr_ibaction_ios.swift:[[@LINE-4]] - @IBAction func watchKitLikeOpt(_: Int?) {} - // CHECK-BOTH: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: argument to @IBAction method cannot have non-object type + @IBAction func ternary(_: AnyObject, _: AnyObject, _: AnyObject) {} + // CHECK-ios: attr_ibaction_ios.swift:[[@LINE-1]]:18: error: @IBAction methods must have at most 2 arguments + // CHECK-macosx: attr_ibaction_ios.swift:[[@LINE-2]]:18: error: @IBAction methods must have 1 argument + // CHECK-tvos: attr_ibaction_ios.swift:[[@LINE-3]]:18: error: @IBAction methods must have at most 2 arguments + // CHECK-watchos: attr_ibaction_ios.swift:[[@LINE-4]]:18: error: @IBAction methods must have at most 2 arguments } diff --git a/test/attr/attr_ibsegueaction.swift b/test/attr/attr_ibsegueaction.swift new file mode 100644 index 00000000000..8323208f570 --- /dev/null +++ b/test/attr/attr_ibsegueaction.swift @@ -0,0 +1,235 @@ +// RUN: %target-typecheck-verify-swift + +// REQUIRES: objc_interop + +@IBSegueAction // expected-error {{@IBSegueAction may only be used on 'func' declarations}} {{1-16=}} +var iboutlet_global: Int + +var iboutlet_accessor: Int { + @IBSegueAction // expected-error {{@IBSegueAction may only be used on 'func' declarations}} {{3-18=}} + get { return 42 } +} + +@IBSegueAction // expected-error {{@IBSegueAction may only be used on 'func' declarations}} {{1-16=}} +class IBOutletClassTy {} +@IBSegueAction // expected-error {{@IBSegueAction may only be used on 'func' declarations}} {{1-16=}} +struct IBStructTy {} + +@IBSegueAction // expected-error {{only instance methods can be declared @IBSegueAction}} {{1-16=}} +func IBFunction(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {} + +class IBActionWrapperTy { + @IBSegueAction + func click(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // no-warning + + func outer(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject { + @IBSegueAction // expected-error {{only instance methods can be declared @IBSegueAction}} {{5-20=}} + func inner(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} + fatalError() + } + @IBSegueAction // expected-error {{@IBSegueAction may only be used on 'func' declarations}} {{3-18=}} + var value : AnyObject? = nil + + @IBSegueAction + func process(x: AnyObject, _: AnyObject, _: AnyObject) {} // expected-error {{methods declared @IBSegueAction must return a value}} + + @IBSegueAction + func process(_: AnyObject, _: AnyObject, _: AnyObject) -> Int? {fatalError()} // expected-error {{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + + // @IBSegueAction does /not/ semantically imply @objc. + @IBSegueAction // expected-note {{attribute already specified here}} + @IBSegueAction // expected-error {{duplicate attribute}} + func doMagic(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {} + + @IBSegueAction @objc + func moreMagic(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {} // no-warning + @objc @IBSegueAction + func evenMoreMagic(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {} // no-warning +} + +struct S { } +enum E { case aCaseToKeepItFromBeingUninhabited } + +protocol P1 { } +protocol P2 { } + +protocol CP1 : class { } +protocol CP2 : class { } + +@objc protocol OP1 { } +@objc protocol OP2 { } + +// Check errors and fix-its for names which would cause memory leaks due to ARC +// semantics. +@objc class Leaky { + @IBSegueAction func newScreen(_: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'newScreen:' because it has special memory management behavior}} + // expected-note@-2{{change Swift name to 'makeScreen'}} {{23-32=makeScreen}} + // expected-note@-3{{change Objective-C selector to 'makeScreen:'}} {{3-3=@objc(makeScreen:) }} + @IBSegueAction func allocScreen(_: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'allocScreen:' because it has special memory management behavior}} + // expected-note@-2{{change Swift name to 'makeScreen'}} {{23-34=makeScreen}} + // expected-note@-3{{change Objective-C selector to 'makeScreen:'}} {{3-3=@objc(makeScreen:) }} + @IBSegueAction func initScreen(_: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'initScreen:' because it has special memory management behavior}} + // expected-note@-2{{change Swift name to 'makeScreen'}} {{23-33=makeScreen}} + // expected-note@-3{{change Objective-C selector to 'makeScreen:'}} {{3-3=@objc(makeScreen:) }} + @IBSegueAction func copyScreen(_: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'copyScreen:' because it has special memory management behavior}} + // expected-note@-2{{change Swift name to 'makeCopyScreen'}} {{23-33=makeCopyScreen}} + // expected-note@-3{{change Objective-C selector to 'makeCopyScreen:'}} {{3-3=@objc(makeCopyScreen:) }} + @IBSegueAction func mutableCopyScreen(_: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'mutableCopyScreen:' because it has special memory management behavior}} + // expected-note@-2{{change Swift name to 'makeMutableCopyScreen'}} {{23-40=makeMutableCopyScreen}} + // expected-note@-3{{change Objective-C selector to 'makeMutableCopyScreen:'}} {{3-3=@objc(makeMutableCopyScreen:) }} + @IBSegueAction func newScreen(_: AnyObject, secondArg: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'newScreen:secondArg:' because it has special memory management behavior}} + // expected-note@-2{{change Swift name to 'makeScreen(_:secondArg:)'}} {{23-32=makeScreen}} + // expected-note@-3{{change Objective-C selector to 'makeScreen:secondArg:'}} {{3-3=@objc(makeScreen:secondArg:) }} + + // If there's an @objc(explicitSelector:) already, we should validate and fix + // that instead of the Swift name. + @objc(actuallyOkayScreen:) + @IBSegueAction func newActuallyOkayScreen(_: AnyObject) -> AnyObject {fatalError()} + + @objc(actuallyOkayScreen:secondArg:) + @IBSegueAction func newActuallyOkayScreen(_: AnyObject, secondArg: AnyObject) -> AnyObject {fatalError()} + + @objc(newProblematicScreen:) + @IBSegueAction func problematicScreen(_: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'newProblematicScreen:' because it has special memory management behavior}} + // expected-note@-2{{change Objective-C selector to 'makeProblematicScreen:'}} {{9-30=makeProblematicScreen:}} + + @objc(newProblematicScreen:secondArg:) + @IBSegueAction func problematicScreen(_: AnyObject, secondArg: AnyObject) -> AnyObject {fatalError()} + // expected-error@-1{{@IBSegueAction method cannot have selector 'newProblematicScreen:secondArg:' because it has special memory management behavior}} + // expected-note@-2{{change Objective-C selector to 'makeProblematicScreen:secondArg:'}} {{9-40=makeProblematicScreen:secondArg:}} +} + +// Check which argument types @IBSegueAction can take. +@objc class X { + // Class type + @IBSegueAction func action1(_: X, _: X, _: X) -> X {fatalError()} + + @IBSegueAction func action2(_: X?, _: X?, _: X?) -> X? {fatalError()} + + @IBSegueAction func action3(_: X!, _: X!, _: X!) -> X! {fatalError()} + + // AnyObject + @IBSegueAction func action4(_: AnyObject, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} + + @IBSegueAction func action5(_: AnyObject?, _: AnyObject?, _: AnyObject?) -> AnyObject? {fatalError()} + + @IBSegueAction func action6(_: AnyObject!, _: AnyObject!, _: AnyObject!) -> AnyObject! {fatalError()} + + // Any + @IBSegueAction func action4a(_: Any, _: Any, _: Any) -> Any {fatalError()} + + @IBSegueAction func action5a(_: Any?, _: Any?, _: Any?) -> Any? {fatalError()} + + @IBSegueAction func action6a(_: Any!, _: Any!, _: Any!) -> Any! {fatalError()} + + // Protocol types + @IBSegueAction func action7a(_: AnyObject, _: AnyObject, _: AnyObject) -> P1 {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'P1' cannot be represented in Objective-C}} + @IBSegueAction func action7b(_: P1, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'P1' cannot be represented in Objective-C}} + @IBSegueAction func action7c(_: AnyObject, _: P1, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'P1' cannot be represented in Objective-C}} + @IBSegueAction func action7d(_: AnyObject, _: AnyObject, _: P1) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'P1' cannot be represented in Objective-C}} + + @IBSegueAction func action8a(_: AnyObject, _: AnyObject, _: AnyObject) -> CP1 {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'CP1' cannot be represented in Objective-C}} + @IBSegueAction func action7b(_: CP1, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'CP1' cannot be represented in Objective-C}} + @IBSegueAction func action7c(_: AnyObject, _: CP1, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'CP1' cannot be represented in Objective-C}} + @IBSegueAction func action7d(_: AnyObject, _: AnyObject, _: CP1) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} expected-note{{protocol-constrained type containing protocol 'CP1' cannot be represented in Objective-C}} + + @IBSegueAction func action9(_: OP1, _: OP1, _: OP1) -> OP1 {fatalError()} + + @IBSegueAction func action10a(_: AnyObject, _: AnyObject, _: AnyObject) -> P1? {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action10b(_: P1?, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action10c(_: AnyObject, _: P1?, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action10d(_: AnyObject, _: AnyObject, _: P1?) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action11a(_: AnyObject, _: AnyObject, _: AnyObject) -> CP1? {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action11b(_: CP1?, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action11c(_: AnyObject, _: CP1?, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action11d(_: AnyObject, _: AnyObject, _: CP1?) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action12(_: OP1?, _: OP1?, _: OP1?) -> OP1? {fatalError()} + + @IBSegueAction func action13a(_: AnyObject, _: AnyObject, _: AnyObject) -> P1! {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action13b(_: P1!, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action13c(_: AnyObject, _: P1!, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action13d(_: AnyObject, _: AnyObject, _: P1!) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action14a(_: AnyObject, _: AnyObject, _: AnyObject) -> CP1! {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action14b(_: CP1!, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action14c(_: AnyObject, _: CP1!, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action14d(_: AnyObject, _: AnyObject, _: CP1!) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action15(_: OP1!, _: OP1!, _: OP1!) -> OP1! {fatalError()} + + // Class metatype + @IBSegueAction func action16a(_: X.Type, _: X.Type, _: X.Type) -> X.Type {fatalError()} + @IBSegueAction func action16b(_: X.Type?, _: X.Type?, _: X.Type?) -> X.Type? {fatalError()} + @IBSegueAction func action16c(_: X.Type!, _: X.Type!, _: X.Type!) -> X.Type! {fatalError()} + + // AnyClass + @IBSegueAction func action18(_: AnyClass, _: AnyClass, _: AnyClass) -> AnyClass {fatalError()} + @IBSegueAction func action19(_: AnyClass?, _: AnyClass?, _: AnyClass?) -> AnyClass? {fatalError()} + @IBSegueAction func action20(_: AnyClass!, _: AnyClass!, _: AnyClass!) -> AnyClass! {fatalError()} + + // Protocol types + @IBSegueAction func action21a(_: AnyObject, _: AnyObject, _: AnyObject) -> P1.Type {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action21b(_: P1.Type, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action21c(_: AnyObject, _: P1.Type, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action21d(_: AnyObject, _: AnyObject, _: P1.Type) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action22a(_: AnyObject, _: AnyObject, _: AnyObject) -> CP1.Type {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action22b(_: CP1.Type, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action22c(_: AnyObject, _: CP1.Type, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action22d(_: AnyObject, _: AnyObject, _: CP1.Type) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action23(_: OP1.Type, _: OP1.Type, _: OP1.Type) -> OP1.Type {fatalError()} + + @IBSegueAction func action24a(_: AnyObject, _: AnyObject, _: AnyObject) -> P1.Type? {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action24b(_: P1.Type?, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action24c(_: AnyObject, _: P1.Type?, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action24d(_: AnyObject, _: AnyObject, _: P1.Type?) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action25a(_: AnyObject, _: AnyObject, _: AnyObject) -> CP1.Type? {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action25b(_: CP1.Type?, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action25c(_: AnyObject, _: CP1.Type?, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action25d(_: AnyObject, _: AnyObject, _: CP1.Type?) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action26(_: OP1.Type?, _: OP1.Type?, _: OP1.Type?) -> OP1.Type? {fatalError()} + + @IBSegueAction func action27a(_: AnyObject, _: AnyObject, _: AnyObject) -> P1.Type! {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action27b(_: P1.Type!, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action27c(_: AnyObject, _: P1.Type!, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action27d(_: AnyObject, _: AnyObject, _: P1.Type!) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action28a(_: AnyObject, _: AnyObject, _: AnyObject) -> CP1.Type! {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} + @IBSegueAction func action28b(_: CP1.Type!, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} + @IBSegueAction func action28c(_: AnyObject, _: CP1.Type!, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} + @IBSegueAction func action28d(_: AnyObject, _: AnyObject, _: CP1.Type!) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} + + @IBSegueAction func action29(_: OP1.Type!, _: OP1.Type!, _: OP1.Type!) -> OP1.Type! {fatalError()} + + // Other bad cases + @IBSegueAction func action30a(_: AnyObject, _: AnyObject, _: AnyObject) -> S {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} expected-note{{Swift structs cannot be represented in Objective-C}} + @IBSegueAction func action30b(_: S, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} expected-note{{Swift structs cannot be represented in Objective-C}} + @IBSegueAction func action30c(_: AnyObject, _: S, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} expected-note{{Swift structs cannot be represented in Objective-C}} + @IBSegueAction func action30d(_: AnyObject, _: AnyObject, _: S) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} expected-note{{Swift structs cannot be represented in Objective-C}} + + @IBSegueAction func action31a(_: AnyObject, _: AnyObject, _: AnyObject) -> E {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because its result type cannot be represented in Objective-C}} expected-note{{non-'@objc' enums cannot be represented in Objective-C}} + @IBSegueAction func action31b(_: E, _: AnyObject, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 1 cannot be represented in Objective-C}} expected-note{{non-'@objc' enums cannot be represented in Objective-C}} + @IBSegueAction func action31c(_: AnyObject, _: E, _: AnyObject) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 2 cannot be represented in Objective-C}} expected-note{{non-'@objc' enums cannot be represented in Objective-C}} + @IBSegueAction func action31d(_: AnyObject, _: AnyObject, _: E) -> AnyObject {fatalError()} // expected-error{{method cannot be marked @IBSegueAction because the type of the parameter 3 cannot be represented in Objective-C}} expected-note{{non-'@objc' enums cannot be represented in Objective-C}} + + // Supported arities + @IBSegueAction func actionWith0() -> X {fatalError()} // expected-error{{@IBSegueAction methods must have 1 to 3 arguments}} + @IBSegueAction func actionWith1(_: X) -> X {fatalError()} + @IBSegueAction func actionWith2(_: X, _: X) -> X {fatalError()} + @IBSegueAction func actionWith3(_: X, _: X, _: X) -> X {fatalError()} + @IBSegueAction func actionWith4(_: X, _: X, _: X, _: X) -> X {fatalError()} // expected-error{{@IBSegueAction methods must have 1 to 3 arguments}} + + init() { } +} diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift index 2f4a7ea7823..8d5c46e7d85 100644 --- a/test/attr/attr_objc.swift +++ b/test/attr/attr_objc.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify -verify-ignore-unknown %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference // RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference | %FileCheck %s // RUN: not %target-swift-frontend -typecheck -dump-ast -disable-objc-attr-requires-foundation-module %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference > %t.ast // RUN: %FileCheck -check-prefix CHECK-DUMP %s < %t.ast @@ -1649,6 +1649,7 @@ class C { // Don't crash. @objc func foo(x: Undeclared) {} // expected-error {{use of undeclared type 'Undeclared'}} @IBAction func myAction(sender: Undeclared) {} // expected-error {{use of undeclared type 'Undeclared'}} + @IBSegueAction func myAction(coder: Undeclared, sender: Undeclared) -> Undeclared {fatalError()} // expected-error {{use of undeclared type 'Undeclared'}} expected-error {{use of undeclared type 'Undeclared'}} expected-error {{use of undeclared type 'Undeclared'}} } //===--- @@ -1681,7 +1682,20 @@ class HasIBAction { // CHECK: {{^}} @objc @IBAction func goodAction(_ sender: AnyObject?) { @IBAction func badAction(_ sender: PlainStruct?) { } - // expected-error@-1{{argument to @IBAction method cannot have non-object type 'PlainStruct?'}} + // expected-error@-1{{method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C}} +} + +//===--- +//===--- @IBSegueAction implies @objc +//===--- + +// CHECK-LABEL: {{^}}class HasIBSegueAction { +class HasIBSegueAction { + @IBSegueAction func goodSegueAction(_ coder: AnyObject) -> AnyObject {fatalError()} + // CHECK: {{^}} @objc @IBSegueAction func goodSegueAction(_ coder: AnyObject) -> AnyObject { + + @IBSegueAction func badSegueAction(_ coder: PlainStruct?) -> Int? {fatalError()} + // expected-error@-1{{method cannot be marked @IBSegueAction because the type of the parameter cannot be represented in Objective-C}} } //===--- diff --git a/test/attr/attr_objc_resilience.swift b/test/attr/attr_objc_resilience.swift index 22829b62094..0afd4cefa6a 100644 --- a/test/attr/attr_objc_resilience.swift +++ b/test/attr/attr_objc_resilience.swift @@ -9,18 +9,18 @@ import Foundation import resilient_objc_class @objc public class ResilientNSObjectSubclass : ResilientNSObjectOutsideParent {} -// expected-error@-1 {{classes built with library evolution support cannot have explicit '@objc' subclasses because they are not directly visible from Objective-C}} +// expected-error@-1 {{explicit '@objc' on subclass of 'ResilientNSObjectOutsideParent' requires}} public class AnotherResilientNSObjectSubclass : ResilientNSObjectOutsideParent {} extension ResilientNSObjectOutsideParent { @objc public func categoryOneMethod() {} - // expected-error@-1 {{extensions of classes built with library evolution support cannot contain '@objc' members}} + // expected-error@-1 {{'@objc' instance method in extension of subclass of 'ResilientNSObjectOutsideParent' requires}} } extension AnotherResilientNSObjectSubclass { @objc public func categoryTwoMethod() {} - // expected-error@-1 {{extensions of classes built with library evolution support cannot contain '@objc' members}} + // expected-error@-1 {{'@objc' instance method in extension of subclass of 'ResilientNSObjectOutsideParent' requires}} } // Note: @_fixed_layout on a class only applies to the storage layout and @@ -28,17 +28,37 @@ extension AnotherResilientNSObjectSubclass { @_fixed_layout @objc public class FixedLayoutNSObjectSubclass : FixedLayoutNSObjectOutsideParent {} -// expected-error@-1 {{classes built with library evolution support cannot have explicit '@objc' subclasses because they are not directly visible from Objective-C}} +// expected-error@-1 {{explicit '@objc' on subclass of 'FixedLayoutNSObjectOutsideParent' requires}} @_fixed_layout public class AnotherFixedLayoutNSObjectSubclass : FixedLayoutNSObjectOutsideParent {} extension FixedLayoutNSObjectOutsideParent { @objc public func categoryOneMethod() {} - // expected-error@-1 {{extensions of classes built with library evolution support cannot contain '@objc' members}} + // expected-error@-1 {{'@objc' instance method in extension of subclass of 'FixedLayoutNSObjectOutsideParent' requires}} } extension AnotherFixedLayoutNSObjectSubclass { @objc public func categoryTwoMethod() {} - // expected-error@-1 {{extensions of classes built with library evolution support cannot contain '@objc' members}} + // expected-error@-1 {{'@objc' instance method in extension of subclass of 'FixedLayoutNSObjectOutsideParent' requires}} +} + +// If either the class or the extension member has sufficiently narrow +// availability, we're okay. +extension AnotherResilientNSObjectSubclass { + @available(macOS 10.15, iOS 13.0.0, tvOS 13.0.0, watchOS 6.0.0, *) + @objc public func availableCategoryOneMethod() {} +} + +extension AnotherResilientNSObjectSubclass { + @available(macOS 10.15, iOS 13.0.0, tvOS 13.0.0, watchOS 6.0.0, *) + @objc public func availableCategoryTwoMethod() {} +} + +@available(macOS 10.15, iOS 13.0.0, tvOS 13.0.0, watchOS 6.0.0, *) +@objc public class AvailableResilientNSObjectSubclass : ResilientNSObjectOutsideParent {} + +@available(macOS 10.15, iOS 13.0.0, tvOS 13.0.0, watchOS 6.0.0, *) +extension AnotherResilientNSObjectSubclass { + @objc public func categoryThreeMethod() {} } diff --git a/test/attr/attr_objc_resilient_stubs.swift b/test/attr/attr_objc_resilient_stubs.swift index 7831a8e1603..f11267df880 100644 --- a/test/attr/attr_objc_resilient_stubs.swift +++ b/test/attr/attr_objc_resilient_stubs.swift @@ -1,14 +1,15 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -emit-module-path %t/resilient_struct.swiftmodule %S/../Inputs/resilient_struct.swift -enable-library-evolution -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module-path %t/resilient_objc_class.swiftmodule %S/../Inputs/resilient_objc_class.swift -I %t -enable-library-evolution -enable-resilient-objc-class-stubs -// RUN: %target-swift-frontend -typecheck -verify %s -I %t -enable-resilient-objc-class-stubs +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module-path %t/resilient_objc_class.swiftmodule %S/../Inputs/resilient_objc_class.swift -I %t -enable-library-evolution -target %target-next-stable-abi-triple +// RUN: %target-swift-frontend -typecheck -verify %s -I %t -target %target-next-stable-abi-triple // REQUIRES: objc_interop +// REQUIRES: swift_stable_abi import Foundation import resilient_objc_class -// When built with -enable-resilient-objc-class-stubs, all of these cases are +// When built with a sufficiently new deployment target, all of these cases are // allowed. @objc public class ResilientNSObjectSubclass : ResilientNSObjectOutsideParent {} diff --git a/test/lit.cfg b/test/lit.cfg index 99e0ba05be1..55a02e99290 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -584,45 +584,62 @@ if config.benchmark_o != 'Benchmark_O': config.substitutions.append(('%target-triple', config.variant_triple)) if run_vendor == 'apple': - # iOS 12.2 does not support 32-bit targets, so we cannot run tests that - # want to deploy to an iOS that has Swift in the OS. - if run_os == 'ios' and run_ptrsize == '32': - pre_stable_version = '10' - else: - config.available_features.add('swift_stable_abi') - PRE_STABLE_VERSION = { - 'macosx': '10.14.3', - 'ios': '12.1', - 'tvos': '12.1', - 'watchos': '5.1' - } - pre_stable_version = PRE_STABLE_VERSION.get(run_os, '') + if True: + # iOS 12.2 does not support 32-bit targets, so we cannot run tests that + # want to deploy to an iOS that has Swift in the OS. + if run_os == 'ios' and run_ptrsize == '32': + pre_stable_version = '10' + else: + config.available_features.add('swift_stable_abi') + PRE_STABLE_VERSION = { + 'macosx': '10.14.3', + 'ios': '12.1', + 'tvos': '12.1', + 'watchos': '5.1' + } + pre_stable_version = PRE_STABLE_VERSION.get(run_os, '') - config.pre_stable_abi_triple = '%s-%s-%s%s' % (run_cpu, run_vendor, run_os, - pre_stable_version) - STABLE_VERSION = { - 'macosx': '10.14.4', - 'ios': '12.2', - 'tvos': '12.2', - 'watchos': '5.2' - } - stable_version = STABLE_VERSION.get(run_os, '') - config.stable_abi_triple = '%s-%s-%s%s' % (run_cpu, run_vendor, run_os, - stable_version) + config.pre_stable_abi_triple = '%s-%s-%s%s' % (run_cpu, run_vendor, run_os, + pre_stable_version) + STABLE_VERSION = { + 'macosx': '10.14.4', + 'ios': '12.2', + 'tvos': '12.2', + 'watchos': '5.2' + } + stable_version = STABLE_VERSION.get(run_os, '') + config.stable_abi_triple = '%s-%s-%s%s' % (run_cpu, run_vendor, run_os, + stable_version) + + NEXT_STABLE_VERSION = { + 'macosx': '10.15', + 'ios': '13', + 'tvos': '13', + 'watchos': '6' + } + next_stable_version = NEXT_STABLE_VERSION.get(run_os, '') + config.next_stable_abi_triple = '%s-%s-%s%s' % (run_cpu, run_vendor, run_os, + next_stable_version) else: config.pre_stable_abi_triple = config.variant_triple config.stable_abi_triple = config.variant_triple + config.next_stable_abi_triple = config.variant_triple # On Apple platforms, this substitution names the maximum OS version *without* # Swift in the OS. On non-Apple platforms this is equivalent to %target-triple. config.substitutions.append(('%target-pre-stable-abi-triple', config.pre_stable_abi_triple)) -# On Apple platforms, this substitution names the minimum OS version *with* -# Swift in the OS. On non-Apple platforms this is equivalent to %target-triple. +# On Apple platforms, this substitution names the minimum OS version with +# Swift 5.0 in the OS. On non-Apple platforms this is equivalent to %target-triple. config.substitutions.append(('%target-stable-abi-triple', config.stable_abi_triple)) +# On Apple platforms, this substitution names the minimum OS version with +# Swift 5.1 in the OS, and an Objective-C runtime supporting class stubs. +config.substitutions.append(('%target-next-stable-abi-triple', + config.next_stable_abi_triple)) + # Sanitizers are not supported on iOS7, yet all tests are configured to start # testing with the earliest supported platform, which happens to be iOS7 for # Swift. diff --git a/test/type/opaque_availability.swift b/test/type/opaque_availability.swift new file mode 100644 index 00000000000..360dcbf7887 --- /dev/null +++ b/test/type/opaque_availability.swift @@ -0,0 +1,13 @@ +// RUN: %target-swift-frontend -parse-stdlib -target x86_64-apple-macosx10.9 -typecheck -verify %s +// RUN: %target-swift-frontend -parse-stdlib -target x86_64-apple-macosx10.15 -typecheck %s +// REQUIRES: OS=macosx + +protocol P {} +struct X: P {} + +func alwaysOpaque() -> some P { return X() } // expected-error{{'some' return types are only available}} expected-note{{add @available}} + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +func sometimesOpaque() -> some P { return X() } + + diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp index d12c1ddc96a..bd8c423d2c1 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp @@ -1274,9 +1274,10 @@ public: } StringRef getObjCSelectorName(const Decl *D, SmallString<64> &Buf) { - // We only vend the selector name for @IBAction methods. + // We only vend the selector name for @IBAction and @IBSegueAction methods. if (auto FuncD = dyn_cast_or_null(D)) { - if (FuncD->getAttrs().hasAttribute()) + if (FuncD->getAttrs().hasAttribute() || + FuncD->getAttrs().hasAttribute()) return FuncD->getObjCSelector().getString(Buf); } return StringRef(); diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp index 0d146bb130e..467089ad40f 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp @@ -665,6 +665,10 @@ Optional SwiftLangSupport::getUIDForDeclAttribute(const swift::DeclAttri case DAK_IBAction: { return Attr_IBAction; } + case DAK_IBSegueAction: { + static UIdent Attr_IBSegueAction("source.decl.attribute.ibsegueaction"); + return Attr_IBSegueAction; + } case DAK_IBOutlet: { return Attr_IBOutlet; } diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index 16259402b6d..38639e02220 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -264,7 +264,7 @@ static llvm::cl::list SwiftVersion("swift-version", llvm::cl::desc("Swift version"), llvm::cl::cat(Category)); -static llvm::cl::opt +static llvm::cl::list ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"), llvm::cl::cat(Category)); @@ -3267,8 +3267,11 @@ int main(int argc, char *argv[]) { InitInvok.getLangOptions().EffectiveLanguageVersion = actual.getValue(); } } - InitInvok.getClangImporterOptions().ModuleCachePath = - options::ModuleCachePath; + if (!options::ModuleCachePath.empty()) { + // Honor the *last* -module-cache-path specified. + InitInvok.getClangImporterOptions().ModuleCachePath = + options::ModuleCachePath[options::ModuleCachePath.size()-1]; + } InitInvok.getClangImporterOptions().PrecompiledHeaderOutputDir = options::PCHOutputDir; InitInvok.setImportSearchPaths(options::ImportPaths); diff --git a/validation-test/Runtime/class_stubs.m b/validation-test/Runtime/class_stubs.m index fd40b1da9f0..03af7438fd7 100644 --- a/validation-test/Runtime/class_stubs.m +++ b/validation-test/Runtime/class_stubs.m @@ -3,14 +3,15 @@ // RUN: %empty-directory(%t) // RUN: %target-build-swift -emit-library -emit-module -o %t/libfirst.dylib -emit-objc-header-path %t/first.h %S/Inputs/class-stubs-from-objc/first.swift -Xlinker -install_name -Xlinker @executable_path/libfirst.dylib -enable-library-evolution -// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -emit-objc-header-path %t/second.h -I %t %S/Inputs/class-stubs-from-objc/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -Xfrontend -enable-resilient-objc-class-stubs +// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -emit-objc-header-path %t/second.h -I %t %S/Inputs/class-stubs-from-objc/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple // RUN: cp %S/Inputs/class-stubs-from-objc/module.map %t/ -// RUN: xcrun %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref +// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref -target %target-next-stable-abi-triple // RUN: %target-codesign %t/main %t/libfirst.dylib %t/libsecond.dylib // RUN: %target-run %t/main %t/libfirst.dylib %t/libsecond.dylib // REQUIRES: executable_test -// REQUIRES: OS=macosx +// REQUIRES: objc_interop +// REQUIRES: swift_stable_abi #import #import diff --git a/validation-test/Runtime/class_stubs_weak.m b/validation-test/Runtime/class_stubs_weak.m index 0b88706576a..dd2330bdd75 100644 --- a/validation-test/Runtime/class_stubs_weak.m +++ b/validation-test/Runtime/class_stubs_weak.m @@ -3,20 +3,21 @@ // RUN: %empty-directory(%t) // RUN: %target-build-swift -emit-library -emit-module -o %t/libfirst.dylib -emit-objc-header-path %t/first.h %S/Inputs/class-stubs-weak/first.swift -Xlinker -install_name -Xlinker @executable_path/libfirst.dylib -enable-library-evolution -// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -emit-objc-header-path %t/second.h -I %t %S/Inputs/class-stubs-weak/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -Xfrontend -enable-resilient-objc-class-stubs -DBEFORE +// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -emit-objc-header-path %t/second.h -I %t %S/Inputs/class-stubs-weak/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple -DBEFORE // RUN: cp %S/Inputs/class-stubs-weak/module.map %t/ // Note: This is the just-built Clang, not the system Clang. // RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref -target %target-triple // Now rebuild the library, omitting the weak-exported class -// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -I %t %S/Inputs/class-stubs-weak/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -Xfrontend -enable-resilient-objc-class-stubs +// RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -I %t %S/Inputs/class-stubs-weak/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple // RUN: %target-codesign %t/main %t/libfirst.dylib %t/libsecond.dylib // RUN: %target-run %t/main %t/libfirst.dylib %t/libsecond.dylib // REQUIRES: executable_test // REQUIRES: objc_interop +// REQUIRES: swift_stable_abi #import #import