This function had a weird, pre-ProtocolConformanceRef interface that
returned true when the type conformed to the protocol, then had a
separate indirect return value for the concrete conformance (if there
is one). Refactor this API, and the similar
TypeChecker::containsProtocol(), to produce an optional
ProtocolConformanceRef, which is far more idiomatic and easier to
use. Push ProtocolConformanceRef into a few more places. Should be NFC
I'm not sure why this didn't occur to me in 8282160d: of course if you
see a generic type with arguments, you need to see the @interface for
that type in order to supply the arguments. Maybe I was thinking the
generated interface would automatically import anything the module
itself imports, but that hasn't ever been true.
rdar://problem/28738008
This flag switches the "effective language version" of the compiler,
at least to any version supported (as of this change: "3" or "3.0").
At the moment nothing uses it except the language version build
configuration statements (#if swift(...)) and various other places
that report, encode, or otherwise check version numbers.
In the future, it's intended as scaffolding for backwards compatibility.
Fixes SR-2582
Simplify e.g., ASTContext::getBridgedToObjC(), which no longer needs
the optional return.
Eliminate the now-unused constraint kind for checking bridging to
Objective-C.
More specifically, don't try to emit a definition for them. Just fall
through to what we do for forward-declarations...which also needed some
fixing, to make sure we don't use a Swift typealias as its underlying
type but never import the underlying type.
https://bugs.swift.org/browse/SR-2352
Like Swift generics, Objective-C generics may have constraints; unlike
Swift generics, Objective-C doesn't do separate parsing and
type-checking passes. This means that any generic arguments for
constrained generic parameters must be fully-defined, in order to
check that they satisfy the constraints.
This commit addresses this problem with three different mechanisms,
one for each kind of declaration that might run into this issue:
- For classes, if a member references a type with constrained generic
parameter, and the corresponding argument type hasn't been printed
yet, that member is "delayed", which means it is put into a category
at the end of the file.
- Protocols cannot have categories, so for protocols we instead see if
we can print the definition of the other type first. To break
circular dependencies, the printer will not attempt this if both the
type and the protocol are already being depended on. This isn't
perfect (see below).
- Rather than delaying members of extensions, we just delay them
wholesale. This keeps related members together, but also has
problems (see below).
These approaches solve the most common cases while still not crashing
in the uncommon ones. However, there are still a number of problems:
- The protocol heuristic is overly negative, which means we may generate
an invalid header even when there's a reasonable ordering. For example,
a single class might inherit from a class A and conform to protocol P,
and protocol P depends on class A as a generic argument. In this case,
defining class A first is the right thing to do, but it's possible for
the printer to decide that there's circularity here and just forward-
declare A instead.
- Protocols really can be circular. This can be fixed by printing a
forward-declared protocol alongside the generic constraints, i.e.
'id <MoreThanNSCopying, NSCopying>' instead of just
'id <MoreThanNSCopying>'.
- Extensions can introduce protocols as well. This is not modeled at
all; if a member depends on a protocol conformance, it's assumed
that simply printing the class would be sufficient. This could be
fixed by checking how a generic argument satisfies its constraints,
possibly delaying individual members from extensions in order to
print them sooner.
- More cases I haven't thought about.
Test cases for some of these problems are in the new
circularity-errors.swift file, mostly to make sure the ObjC printer
doesn't crash when it encounters them.
rdar://problem/27109377
...because otherwise option sets that get imported as members using
NS_SWIFT_NAME are printed with an 'enum' tag, and the definition of
NS_OPTIONS only declares the typedef under C++.
We should come back and figure out something more principled for this
later, but for now this solves an issue with generated headers
imported into C++ translation units.
rdar://problem/27130343
Don't allow types conforming to 'Error' or protocol compositions
involving 'Error' to be reflected in Objective-C. We still allow
bridging conversions, but they are not statically bridged. Fixes
SR-2249/rdar://problem/27658940.
We would crash because 'Any' doesn't have a corresponding bridged type through the normal bridging mechanism. Handle this correctly, and correctly recognize 'AnyHashable' and 'Any' as the upper bounds of Dictionary, Set, and Array so we present the unqualified NS types in the generated header.
* [PrintAsObjC] Add unavailable attribute to non-inherited initializers
Initializers that aren't inherited by subclasses cannot be called, so we
should make this visible to Obj-C.
Due to SR-2211, non-inherited convenience initializers do not get this
same treatment.
* [PrintAsObjC] Add unavailable initializers for private overrides
When a public initializer is overridden with a private one, we need to
mark these as unavailable to Obj-C as they're not supposed to be
callable even though they do exist.
* Migrate from `UnsafePointer<Void>` to `UnsafeRawPointer`.
As proposed in SE-0107: UnsafeRawPointer.
`void*` imports as `UnsafeMutableRawPointer`.
`const void*` imports as `UnsafeRawPointer`.
Occurrences of `UnsafePointer<Void>` are replaced with UnsafeRawPointer.
* Migrate overlays from UnsafePointer<Void> to UnsafeRawPointer.
This requires explicit memory binding in several places,
particularly in NSData and CoreAudio.
* Fix a bunch of test cases for Void->Raw migration.
* qsort takes IUO values
* Bridge `Unsafe[Mutable]RawPointer as `void [const] *`.
* Parse #dsohandle as UnsafeMutableRawPointer
* Update a bunch of test cases for Void->Raw migration.
* Trivial fix for the SceneKit test case.
* Add an UnsafeRawPointer self initializer.
This is unfortunately necessary for assignment between types imported from C.
* Tiny simplification of the initializer.
* Migrate from `UnsafePointer<Void>` to `UnsafeRawPointer`.
As proposed in SE-0107: UnsafeRawPointer.
`void*` imports as `UnsafeMutableRawPointer`.
`const void*` imports as `UnsafeRawPointer`.
Occurrences of `UnsafePointer<Void>` are replaced with UnsafeRawPointer.
* Migrate overlays from UnsafePointer<Void> to UnsafeRawPointer.
This requires explicit memory binding in several places,
particularly in NSData and CoreAudio.
* Fix a bunch of test cases for Void->Raw migration.
* qsort takes IUO values
* Bridge `Unsafe[Mutable]RawPointer as `void [const] *`.
* Parse #dsohandle as UnsafeMutableRawPointer
* Update a bunch of test cases for Void->Raw migration.
* Trivial fix for the SceneKit test case.
* Add an UnsafeRawPointer self initializer.
This is unfortunately necessary for assignment between types imported from C.
* Tiny simplification of the initializer.
It sounds good on paper, but in practice we ended up breaking Core Data
projects (because people name their boolean properties 'isFoo' rather
than the Objective-C 'foo'), forcing an Objective-C-side change when
a mixed-source project upgrades to Swift 3, and causing collisions when
there are properties named both 'foo' and 'isFoo'. If people care about
their Swift boolean properties strictly following the Objective-C Cocoa
naming conventions, they'll have to specify them manually.
(We do have a bug to make it easier to rename the getter of a stored
property exposed to Objective-C: rdar://problem/21261564.)
This reverts commit 6fe6266c99.
rdar://problem/26847223
This flag tracks whether we have a special kind of imported class
that has limitations in what you can do with it. Currently it's
used for two things: CF classes, and the magic "Protocol" class used
to represent Objective-C protocol metadata. I'm planning to add a
third to handle classes with the recently-added objc_runtime_visible
attribute, which describes an Objective-C class whose runtime symbols
are hidden (forcibly preventing categories and subclassing). This is
used for some of the types in Dispatch, which has exposed some of the
classes that were considered implementation details on past OSs.
I'm splitting the flag into an enum rather than just marking the
Dispatch classes with the existing flag because we still need to
be able to /cast/ to the Dispatch types (which you can't do with CF
types today) and because they deserve better than to be lumped in
with CF for diagnostic purposes.
Groundwork for rdar://problem/26850367, which is that Swift will
happily let you extend the new Dispatch classes but then fails to find
the symbols at link-time.
If a class member doesn't have a doc comment but a base class does, show
the base class's comment and add a note about where it came from.
rdar://problem/16512247
Bridged value types are implicitly copied as part of bridging.
This isn't 100% correct because it doesn't handle bridged types
that /don't/ conform to NSCopying, but there aren't any of those
today and there probably shouldn't be.
rdar://problem/26917017
public static var myDictionary: [String: AnyObject]
becomes
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy)
NSDictionary<NSString *, id> * _Nonnull myDictionary;)
and the commas in the ObjC generic break the macro, just like they do with
C++ templates. Fix this by making the macro variadic.
rdar://problem/26879147
Under ARC, methods in the "init" family are considered to have
NS_REPLACES_RECEIVER semantics ("consumes" self and returning a
value at +1). This is correct for Objective-C "init methods",
which are equivalent for Swift's initializers, but almost never
correct for any other methods that happen to start with the word
"init".
Note that Swift still follows all the other ARC conventions, so
if you name a method or property, say, "newItemController", the
value will be returned at +1. For methods this is probably
desirable, but for properties maybe not. We could do something
similar for property accessors to make sure they always have
the default "no method family" semantics in Objective-C.
rdar://problem/25759260
A typedef with the swift_newtype attribute is imported as a struct
wrapping the underlying type instead of just a typealias. If the
underlying type is a bridged type (like String), the newtype struct
is bridged as well. However, we don't want to use that type when
bridging back to Objective-C, because
(1) Objective-C header generation is done too late to fill out the
_ObjectiveCBridgeable conformance for the type, so if it wasn't
type-checked then the conformance won't have the original type
in it.
(2) There's a perfectly good typedef we should be using anyway.
Just use the type as written in Objective-C (instead of crashing).
Finishes rdar://problem/26372925.
(and enums)
Previously this part of the compiler assumed that any imported
struct or enum would have the same name as it does in C, which is
no longer true.
Part of rdar://problem/26372925
There's not yet a released version of Apple Clang that supports
Objective-C class properties, so make sure the generated header
guards any uses of them with a __has_feature check, and provides
declarations of the accessor methods as well.
https://bugs.swift.org/browse/SR-1442
Implements SE-0055: https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md
- Add NULL as an extra inhabitant of Builtin.RawPointer (currently
hardcoded to 0 rather than being target-dependent).
- Import non-object pointers as Optional/IUO when nullable/null_unspecified
(like everything else).
- Change the type checker's *-to-pointer conversions to handle a layer of
optional.
- Use 'AutoreleasingUnsafeMutablePointer<NSError?>?' as the type of error
parameters exported to Objective-C.
- Drop NilLiteralConvertible conformance for all pointer types.
- Update the standard library and then all the tests.
I've decided to leave this commit only updating existing tests; any new
tests will come in the following commits. (That may mean some additional
implementation work to follow.)
The other major piece that's missing here is migration. I'm hoping we get
a lot of that with Swift 1.1's work for optional object references, but
I still need to investigate.
For the most part this was just "check isInstanceProperty"; the one feature not yet implemented
is the emission of ObjC metadata for class properties.
rdar://problem/16830785
Rather than hardcoding String/Array/Dictionary/Set to print as
NSString/NSArray/NSDictionary/NSSet, use _ObjectiveCBridgeable
conformances to determine how to print them. Another step toward
generalized _ObjectiveCBridgeable, although the general form is not
yet useful.
There's an immediate need for this in the core libs, and we have most of the necessary pieces on hand to make it easy to implement. This is an unpolished initial implementation, with the following limitations, among others:
- It doesn't support bridging error conventions,
- It relies on ObjC interop,
- It doesn't check for symbol name collisions,
- It has an underscored name with required symbol name `@cdecl("symbol_name")`, awaiting official bikeshed painting.
Otherwise, we cram a conventionally UpperCamelCase thing with a
newly-conventinally-lowerCamelCased thing together and destroy the
word boundaries. Fixes rdar://problem/24947695.
Including the argument names helps code completion in Xcode.
Fixes SR-365.
Also fixes an issue where a property of a block/function type whose name
is a clang keyword would produce an invalid declaration, e.g.
var `struct`: (Int -> Int)?
was printing as
@property (nonatomic, copy, getter=struct, setter=setStruct:) NSInteger (^ _Nullable struct)(NSInteger)_;
The Objective-C Cocoa convention eschew "is" on property names, but
use it on the getter, while the Swift API guidelines state that
Boolean properties should read as assertions (e.g., "isEmpty" rather
than "empty"). Map Swift properties named "isFoo" to Objective-C by
removing the "is" from the resulting Objective-C property name (so it
will be named "foo") and from the setter (which will have the
Objective-C selector "setFoo:") while retaining the "is" for the
getter selector ("isFoo").
Fixes rdar://problem/17090661.
Also make sure the `FooDomain` constant for `ErrorType` enums uses the
correct name.
Fixes SR-693: Custom named @objc enum still exposes original Swift name
in Objective-C