In Swift 3:
1) a closure referring to $1 or above type checked against a function type that takes a single tuple argument with that arity
2) a closure referring only to $0 (or $0.1 etc) type checked against a function type that takes multiple arguments
but neither compiles in Swift 4.
This patch migrates shorthand references for
1) by prefixing "0." in front of the existing references, e.g. "$1" to "$0.1"
2) by removing the leading 0. if one existing or substituting a tuple of the correct arity if it doesn't, e.g. "$0.1" to "$1" and "$0" to "($0, $1, $2)"
Resolves rdar://problem/31969538
This allows the migrator to pick up fix-its from notes such as:
“Argument of #selector refers to instance method '___' that is not
exposed to Objective-C”
Add some more testing for minimal/complete workflows, and upstream
the cross-file fix-it test.
rdar://problem/32228948
Some diagnostics showing up during migration may not have valid source
locations, so we obviously can't map that onto a buffer onto which we'd
apply a fix-it.
rdar://problem/32213595
If the replacement type was a function type or protocol-constrained type (e.g. 'Class & Proto) and the existing type had a postfix ? or !, we weren't wrapping the replacement in parens. This would result in an incorrect/ambiguous new type. This patch wraps the replacement in parens if it contains an & or ->, the existing type has a trailing ? or !.
Resolves rdar://problem/32082269.
The SyntacticMigratorPass is getting Too Big To Fail and covers
multiple migrations. There was already an early exit to not run
the pass if APIDigesterDataStorePath wasn't supplied, so SE-0110
tuple splat fix-its weren't getting run. This manifested in Migrator
tests not printing migrated contents on Linux.
New: ASTMigratorPass
Renamed: SyntacticMigratorPass -> APIDiffMigratorPass
New: TupleSplatMigratorPass
These implementations are entirely hidden and can only be invoked
by a swift::migrator function.
rdar://problem/32025974
This changed to be resolved by overload resolution in Swift 4, and so
can suddenly be shadowed by similarly named properties and functions
that are visible at the expression's location. When in Swift 3 mode, if
there is a visible declaration named "type", add the `Swift.` prefix to
disambiguate in Swift 4 mode.
rdar://problem/31997321
The warnings about deprecated @objc inference in Swift 3 mode can be a
bit annoying; and are mostly relevant to the migration workflow. Make
the warning emission a three-state switch:
* None (the default): don't warn about these issues.
* Minimal (-warn-swift3-objc-inference-minimal): warn about direct
uses of @objc entrypoints and provide "@objc" Fix-Its for them.
* Complete (-warn-swift3-objc-inference-complete): warn about all
cases where Swift 3 infers @objc but Swift 4 will not.
Fixes rdar://problem/31922278.
Based on recommendations in SE-0160, there are two migration workflows:
- Conservative: Maintain @objc visibility that was inferred in Swift 3
by adding @objc to all declarations that were implicitily visible to
the Objective-C runtime. This is invoked in the migrator by adding the
-migrate-keep-objc-visibility flag.
- Minimal: Only declarations that must be visible to Objective-C based
on their uses (or in cases like dynamic vars) are migrated.
rdar://problem/31876357
This handles optionality changes and type rewrites in function param and return types and constructor param and failability types.
Resolves rdar://problem/31766010
In the Migrator, the AST passes (effectively syntactic edits only)
run before the fix-it passes. We try to reuse as much as possible
from the original CompilerInvocation, but we need to replace the
primary input. Nuking all of the inputs is a bit foolish :-).
rdar://problem/31858212
I had set up the driver to invoke a separate frontend invocation with
the "update code" mode. We sort of did this last release, except we
forked to the swift-update binary instead. This is causing problems with
testing in Xcode.
Instead, let's perform a single compile and add the remap file as an
additional output during normal compiles. The driver, seeing
-update-code, will add -emit-remap-file-path $PATH to the -c frontend
invocation.
rdar://problem/31857580
When running the fix-it passes, we should explicitly set the effective
language version to 4, since passing language version 3 may be the
default at first.
rdar://problem/31854159
This filter is used for both applying fix-its during the normal
migration flow and by the -emit-fixits-path output for a normal
-typecheck frontend invocation, for example.
rdar://problem/30926261
This adds an adapter class that wraps Clang's lib/Edit
Commit and EditedSource classes for use in the initial
"syntactic" passes. Once the passes have completed,
the resulting source file is then passed to the Swift compiler
fix-it passes.
rdar://problem/30926261
These data files are installed into runtime resource directory so that migrator can pick them automatically according to specific platforms. To support testing, a front-end option -api-diff-data-file can be used to specify the data file to use and it will overwrite the default ones from resource directory.
The Swift 4 Migrator is invoked through either the driver and frontend
with the -update-code flag.
The basic pipeline in the frontend is:
- Perform some list of syntactic fixes (there are currently none).
- Perform N rounds of sema fix-its on the primary input file, currently
set to 7 based on prior migrator seasons. Right now, this is just set
to take any fix-it suggested by the compiler.
- Emit a replacement map file, a JSON file describing replacements to a
file that Xcode knows how to understand.
Currently, the Migrator maintains a history of migration states along
the way for debugging purposes.
- Add -emit-remap frontend option
This will indicate the EmitRemap frontend action.
- Don't fork to a separte swift-update binary.
This is going to be a mode of the compiler, invoked by the same flags.
- Add -disable-migrator-fixits option
Useful for debugging, this skips the phase in the Migrator that
automatically applies fix-its suggested by the compiler.
- Add -emit-migrated-file-path option
This is used for testing/debugging scenarios. This takes the final
migration state's output text and writes it to the file specified
by this option.
- Add -dump-migration-states-dir
This dumps all of the migration states encountered during a migration
run for a file to the given directory. For example, the compiler
fix-it migration pass dumps the input file, the output file, and the
remap file between the two.
State output has the following naming convention:
${Index}-${MigrationPassName}-${What}.${extension}, such as:
1-FixitMigrationState-Input.swift
rdar://problem/30926261