SE-0022: Deprecate string-literal-as-selector in favor of #selector.

Introduce Fix-Its to aid migration from selectors spelled as string
literals ("foo:bar:", which is deprecated), as well as from
construction of Selector instances from string literals
(Selector("foo:bar"), which is still acceptable but not recommended),
to the #selector syntax. Jump through some hoops to disambiguate
method references if there are overloads:

    fixits.swift:51:7: warning: use of string literal for Objective-C
         selectors is deprecated; use '#selector' instead
      _ = "overloadedWithInt:" as Selector
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          #selector(Bar.overloaded(_:) as (Bar) -> (Int) -> ())

In the cases where we cannot provide a Fix-It to a #selector
expression, we wrap the string literal in a Selector(...) construction
to suppress the deprecation warning. These are also easily searchable
in the code base.

This also means we're doing more validation of the string literals
that go into Selector, i.e., that they are well-formed selectors and
that we know about some method that is @objc and has that
selector. We'll warn if either is untrue.
This commit is contained in:
Doug Gregor
2016-01-28 10:08:06 -08:00
parent b5ca9e16eb
commit 1a830fa541
18 changed files with 677 additions and 6 deletions

View File

@@ -1408,6 +1408,25 @@ void ModuleFile::lookupClassMembers(Module::AccessPathTy accessPath,
}
}
void ModuleFile::lookupObjCMethods(
ObjCSelector selector,
SmallVectorImpl<AbstractFunctionDecl *> &results) {
// If we don't have an Objective-C method table, there's nothing to do.
if (!ObjCMethods) return;
// Look for all methods in the module file with this selector.
auto known = ObjCMethods->find(selector);
if (known == ObjCMethods->end()) return;
auto found = *known;
for (const auto &result : found) {
// Deserialize the method and add it to the list.
if (auto func = dyn_cast_or_null<AbstractFunctionDecl>(
getDecl(std::get<2>(result))))
results.push_back(func);
}
}
void
ModuleFile::collectLinkLibraries(Module::LinkLibraryCallback callback) const {
for (auto &lib : LinkLibraries)