We used to diagnose references to unavailable declarations in
two places:
- inside Exprs, right after type checking the expression
- inside TypeReprs, from resolveType()
In broad terms, resolveType() is called with TypeReprs
stored inside both Stmts and Decls.
To handle the first case, I added a new overload of
diagAvailability() that takes a Stmt, to be called from
typeCheckStmt(). This doesn't actually walk into any Exprs
stored inside the statement; this means it only walks
Patterns and such.
For the second case, a new DeclAvailabilityChecker is
now defined in TypeCheckAccess.cpp. It's structure is
analogous to the other three walkers there:
- AccessControlChecker
- UsableFromInlineChecker
- ExportabilityChecker
The new implementation of availability checking for types
introduces a lot more code than the old online logic
it replaces. However, I hope to consolidate some of the
code duplication among the four checkers that are defined
in TypeCheckAccess.cpp, and do some other cleanups that
will make the benefit of the new approach apparent.
We don't use this feature anymore (see 0149129ed), and now that we've
branched Swift 5.0 for the last time it's time to rip it out of swiftc
(and then from Clang).
No functionality change, unless someone was compiling their own API
notes. If you were doing that, just copy them into place as text.
Replace `#import` with `#include` as `#import` is a Microsoft type
library inclusion feature on Windows. This enables additional APINotes
tests to pass on Windows.
For the most part, this moves 3/4 tests to 4/5 tests. There are
some interesting changes here because API notes for 4 also apply
to 3 unless otherwise specified, and 4.2 is the next version after
4 rather than 5, but everything should still be correct and testing
useful stuff.
If the Clang declrations are *types*, canonical declaration in Swift is
imported for newest version of Swift. In interface generation, if the
declaration is versioned and it's imported as a member in either or both
version of Swift, we have to take compatibility typealias into account.
* Fixed 'ClangModuleUnit::getTopLevelDecls' to take isCompatibilityAlias() into account
* Fixed bugs in ClangImporter where member-to-member versioned types aren't properly imported.
* Fixed 'SwiftDeclConverter::importFullName' to check equality of getEffectiveContext()
* Fixed 'importer::addEntryToLookupTable' to check equality of getEffectiveContext()
(moved 'ClangImporter::Implementation::forEachDistinctName' to 'NameImporter')
In APINotes, when an unversioned name overrides
a previously declared name with a Swift version, if the
previously declared name is guarded under version 4
the obsoleted version should be 4.2, not 5. In all other
cases, the obsoleted version is the next major Swift
version.
Fixes rdar://problem/39950937
*** Depends on Clang change "[APINotes] Record what version caused ***
*** an annotation to get replaced." Update your Clang checkout! ***
More generally, change the meaning of the SwiftVersions section in API
notes to be "this version or earlier" rather than "exactly this
version". We mostly get this behavior for free from the Clang-side
changes, but for SwiftName and the enum annotations we look at inactive
attributes as well. The latter is simple, but the former means being
careful about finding the annotation we /would/ have picked, i.e. the
one closest to the version we requested.
...because they make things harder for people trying to use
Swift.print. Before:
error: 'print' has been renamed to 'printDocument(_:)'
After:
error: use of 'print' nearly matches global function
'print(_:separator:terminator:)' in module 'Swift'
rather than instance method 'print(_:extra:)'
(This actually occurs with AppKit's NSDocument, so it's not just a
hypothetical concern.)
rdar://problem/32839733
The behavior in versioned-objc.swift changes now that we've fixed
this, since we always prefer to use a type's Swift 4 name. A handful
of new tests have also been added to versioned.swift.
Also lays the groundwork for rdar://problem/16513537, which is about
being able to find an enum by its original top-level name so that we
can show a diagnostic for that. I'll file a public bug about that
later.
rdar://problem/31893305
When a swift_wrapper'd type is renamed from Swift 3 -> 4, we create a
typealias for it. We need to look through that typealias when
deserializing members of that type, e.g., global variables of the
swift_wrapper'd type.
Generic Objective-C classes with this annotation will be imported as
non-generic in Swift. The Swift 3 behavior hardcoded a certain set of
class /hierarchies/ as permanently non-generic, and this is preserved
in Swift 3 mode.
Actually using this API note in a versioned way (as opposed to just
marking the class non-generic in all language versions) will cause
horrible source compatibility problems in the mix-and-match cases,
where Swift 3 code presents a non-generic type that Swift 4 expects to
be generic or vice versa. Fixes for this will come later; right now
it's more important to add support for the feature at all.
To avoid unwanted changes in Swift 4, this commit also adds API notes
to make any existing classes in the previously-hardcoded set continue
to import as non-generic even in Swift 4. The difference is that
/subclasses/ of these classes may come in as generic. (If we want to
make a change here, that can be a separate commit.)
rdar://problem/31226414 (Swift side of rdar://problem/28455962)
If a top-level declaration is imported as a member in Swift 4 but not
in Swift 3, it would still show up in the lookup table for the
containing type in Swift 3 mode. We would import it, and then try to
add the top-level declaration to the containing type.
I'm about to redo this anyway so that the versioned stub will show up
(the one for the Swift 4 name) but this is the narrow fix that avoids
the assertion failure we were seeing.
rdar://problem/31161489
Unlike values, we can't import multiple copies of types under
different names and get good results. Instead, we make a typealias
that points back to the original type. Make sure this typealias is
flagged with whatever version is appropriate, rather than always using
"Swift 2".
When a C declaration is marked unavailable with a replacement, we look
for the replacement to see how it would be imported into Swift. Make
sure we do that with respect to the active language version.
This doesn't actually have any effect yet, but if we start importing
both Swift 3 and Swift 4 versions of protocol requirements and the
non-active one is unavailable, we might mistakenly mark the protocol
un-implementable even when the requirements that are needed are all
there. (Hopefully we would never make a protocol /less/ available in a
newer release, of course.) The test case is designed to catch that.
When importing a property as accessor methods (rather than as a
property), we were still importing the type of the accessor methods as
if they were Swift getters and setters of a property, which
(necessarily) homogenizes the types. The homogenization is unnecessary
when importing as accessor methods, because the methods are
independent, so just import the accessor method types as if the
property did not exist. This is particularly useful for maintaining
Swift 3 source compatibility for cases where Swift 4 turns a
getter/setter pair into a null_resettable property.
Fixes rdar://problem/30075571.
Swift side of this new flag. This allows Objective-C framework authors
to replace a pair of methods by properties without breaking source
compatibility. This is especially important for class properties,
which were only introduced last year.
Still to come: importing the accessors even when this flag isn't set,
in order to provide better QoI when migrating from a method interface
to a property interface.
Part of rdar://problem/28455962
Clang now accepts an option -fapinotes-swift-version=XX that describes
which Swift version to use when applying API notes to the Clang
AST. Pass this option down to Clang based on the Swift major version
number (e.g., 3 or 4), allowing API notes to introduce
Swift-version-specific behavior.
Fixes rdar://problem/28617631.
Enable newly-introduced Clang functionality to load API notes stored
alongside the headers for a module or, for a framework, in an APINotes
subdirectory within the framework. Fixes rdar://problem/28455644.
This can be used as QoI for things like 'NSASCIIStringEncoding', which
is going to canonically be `String.Encoding.ascii` if/when SE-0086 is
accepted.
We can't actually handle this in NS_SWIFT_NAME (that is, we can't
/import/ something onto a nested type), but that's okay: we already
have stricter limitations on NS_SWIFT_NAME enforced by Clang.
rdar://problem/26352374
Using Clang to compile API notes introduces a dependency on the
underlying Clang, which can cause problems as Clang's support for API
notes evolves. Re-introduce the "-apinotes" driver flag into the Swift
driver to allow us to compile API notes, and use that (rather than
Clang) to precompile API notes for the overlays.
This requires a bit of special handling because we override the getter's type
in the importer, to make sure it's compatible with the setter, but other than
that we just use the information from the apinotes file.
<rdar://problem/17891179>
Swift SVN r21027
This allows us to express required initializers in the API notes. Use
it to smooth over NSString differences in the various SDKs even more.
Swift SVN r20511
The converter silently drops the API which are available only on a OS different from the specified "target".
I've restructured the code so that we would not have to pass the parameters around.
TODO:
- Make the traget argument required.
- Use it in the build system when building swift
- Add a test case for when the whole framework is missing. (Tested manually.)
Swift SVN r20464