Compatibility header may #import bridging header if specified with -import-underlying-module.
How these two headers are relative to each other is subject to project setting. To accommodate
this, we should allow users to specify bridging header directory for header generating purposes.
rdar://59110975
When an @_implementationOnly import includes Objective-C categories
for existing types, it's useful to be able to override the members
provided in those categories without exposing them to clients of the
framework being built. Allow this as long as the overriding
declaration is marked as @_implementationOnly itself, with an
additional check that the type of the declaration does not change.
(Normally overrides are allowed to change in covariant ways.)
Part of rdar://50827914
Without -enable-resilient-objc-class-stubs, don't print classes with
resilient ancestry at all, since they're not actually visible to
Clang and referencing one will not actually work.
When the flag is specified, such classes do appear in the generated
header with the new objc_class_stub Clang attribute.
This ensures that 'Foo' always gets imported before 'Foo_Private'.
This shouldn't strictly be necessary but does end up with more
reliable results in practice.
rdar://problem/36159006
This allows them to be used in generic arguments for NSArray et al.
We already do this for the ones that wrap bridged values (like
NSString/String), but failed to do it for objects that /weren't/
bridged to Swift values (class instances and protocol compositions),
or for Error-which-is-special.
In addition to this being a sensible thing to do, /not/ doing this led
to IRGen getting very confused (i.e. crashing) when we imported a
Objective-C protocol that actually used an NS_TYPED_ENUM in this way.
(We actually shouldn't be using Swift's IRGen logic to emit protocol
descriptors for imported protocols at all, because it's possible we
weren't able to import all the requirements. But that's a separate
issue.)
https://bugs.swift.org/browse/SR-6844
The general policy has been that even if something crashes at run
time, we don't make it a hard error in Swift 4 mode (or Swift 3 mode!)
if it wasn't a hard error in Swift 4.0 (3.0). In this case, we thought
we could get away with it, and then it turns out it actually caused
some problems. (And as 2bc010681 shows, we can still make mistakes.)
This change isn't perfect because the diagnostic appears in /clients/
rather than in the module that's being compiled as Swift 4 (instead of
Swift 5). But it still means that someone who hasn't changed
/anything/ from a valid Swift 4.0 project will be able to compile
without any changes, even if they were relying on being able to call
+new when -init was unavailable for some reason.
More rdar://problem/35942058
SourceKit uses a clever pragma to automatically attach an attribute to
every declaration in the file. However, the form of this pragma (clang
attribute push) uses a parenthesized list marked with 'any', which turns
out to be a name that people sometimes use for macros. Guard against this
using the push_macro pragma (originally from MSVC), under the assumption
that anyone who supports the highly-use-specific 'external_source_symbol'
attribute probably implements this more common extension. This does make
the generated header a little uglier, but it's not like it was really
pretty to begin with.
rdar://problem/34168022
Since Swift 3 and Swift 4 might have different views of an Objective-C
API's nullability, we can end up with incompatible overrides,
including with inherited initializers. This is unfortunate but also
realistic; the Swift 3 code is /not/ set up to handle the new nullability
used by Swift 4 and Objective-C. Just silence the warning.
(It would be nice to not print inherited initializers at all, but that
would mean making sure there are no convenience initializers we have
to print as well. Otherwise the class would get mistaken for one
without explicit designated initializers.)
rdar://problem/32571301
These are TypeAliasDecls whose Clang nodes are not TypedefNameDecls.
This worked all right for classes, but dropped the tag keyword
(e.g. 'struct') for tag decls with names of their own, and didn't
print any name at all for C types that used the
typedef-for-anonymous-tag pattern.
rdar://problem/32514335
For historic reasons, Clang's representation of an Objective-C class
declaration ObjCInterfaceDecl) and compatibility alias
(ObjCCompatibleAliasDecl) are not actually Clang TypeDecl nodes. Cope
with this in Objective-C printing, fixing rdar://problem/32308192.
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
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
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
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
Compiler output at least up to serialization should be deterministic at this point,
at least when not taking SIL into account. This /should/ mean that changing a
function body should not affect the final built swiftmodule, which means downstream
targets don't need to be rebuilt. Leaving the previous swiftmodule output in place
signals that.
A while back I put in a push to get all the non-determinism out of type checking,
importing, and serialization itself; it looks like we've finally made it. Let's keep
it that way!
rdar://problem/20539158 and others
Swift SVN r29923
Adding the following to a doc comment:
- throws: ...
Will create a description about what/when the function will throw.
This should be a peer to "- returns:" and "- parameter:" and not appear
inline in the description.
rdar://problem/21621679
Swift SVN r29831
We were printing getter/setter names when the property came from
Objective-C initially, which is incorrect: we should print them when
the names differ from what Objective-C would compute by default. This
finishes rdar://problem/19408726, which was mostly in place a while
ago.
Swift SVN r28783
Mixed-source targets generally include the generated <Product>-Swift.h
header in many Objective-C (.m) source files. Any change to a Swift file
results in the header being touched, which means all the .m files get
recompiled.
This change makes Swift write the generated header to a temporary file
first, then use the previous commit's moveFileIfDifferent to put it in
its final destination.
rdar://problem/20553459
Swift SVN r28042
Printing Doxygen isn't inside an XML tag, so we can't just print
code block content, which may have new lines without a doc comment
marker. Also, be more robust with indentation.
+ Tests.
rdar://problem/20703026
Swift SVN r27851
Replace ReST-flavored documentation comments with Markdown.
rdar://problem/20180412
In addition to full Markdown support, the following extensions are
supported. These appear as lists at the top level of the comment's
"document". All of these extensions are matched without regard to
case.
Parameter Outlines
------------------
- Parameters:
- x: ...
- y: ...
Separate Parameters
-------------------
- parameter x: ...
- parameter y: ...
- Note:
Parameter documentation may be broken up across the entire comment,
with a mix of parameter documentation kinds - they'll be consolidated
in the end.
Returns
-------
- returns: ...
The following extensions are also list items at the top level, which
will also appear in Xcode QuickHelp as first-class citizens:
- Attention: ...
- Author: ...
- Authors: ...
- Bug: ...
- Complexity: ...
- Copyright: ...
- Date: ...
- Experiment: ...
- Important: ...
- Invariant: ...
- Note: ...
- Postcondition: ...
- Precondition: ...
- Remark: ...
- Remarks: ...
- See: ...
- Since: ...
- Todo: ...
- Version: ...
- Warning: ...
These match most of the extra fields in Doxygen, plus a few more per request.
Other changes
-------------
- Remove use of rawHTML for all markup AST nodes except for those
not representable by the Xcode QuickHelp XSLT - <h>, <hr/>, and of
course inline/block HTML itself.
- Update the doc comment RNG schema to more accurately reflect Xcode
QuickHelp.
- Clean up cmark CMake configuration.
- Rename "FullComment" to "DocComment"
- Update the Swift Standard Documentation (in a follow-up commit)
- Update SourceKit for minor changes and link against cmark
(in a follow-up commit).
Swift SVN r27727
...and then fix our forward-declaration logic that assumed that they did.
This fixes a rare case where we would end up printing "enum" twice if the
user (benignly) misused NS_ENUM.
rdar://problem/19769964
Swift SVN r25143
If a property, method, or subscript overrides an imported property, method,
or subscript that was originally declared using NSUInteger as a property,
parameter, or return type, print the subclass's member using "NSUInteger"
in the generated header to prevent override warnings.
This doesn't handle all cases--in particular, it doesn't handle the
NSUInteger being nested inside a larger type--but it does get the easy
ones correct. I think the easiest way to be more correct would be to mark
NSUInteger-as-Int somehow using a distinct type. (Hidden attribute?
Another typealias? Not sure.)
rdar://problem/19321126
Swift SVN r24771