When solving for code completion, we ignore missing arguments after the one
containing the code completion location, don't favor overloads with a number of
params matching the number of arguments in a call and so on. Because of this,
we can't assume multiple solutions being formed when solving for code completion
means there won't be a single best solution formed when solving for regular
type-checking.
Resolves rdar://problem/72362275
`_Nullable_result` indicates that a parameter of a completion handler
should be imported as optional when the completion handler can fail by
throwing an error.
Implements rdar://70108088.
Extend the set of completion-handler names we look for to infer an
`async` import of an Objective-C method, which includes:
* (with)CompletionBlock
* (with)reply
* (with)replyTo
both as parameter names and as base name suffixes.
When mirroring declarations from protocols, make sure to mirror for
all potential imported names. Otherwise, we might miss out on one or
the other of an async import or a completion-handler import of the
same method.
Fixes rdar://71429577.
Following on from updating regular member completion, this hooks up unresolved
member completion (i.e. .<complete here>) to the typeCheckForCodeCompletion API
to generate completions from all solutions the constraint solver produces (even
those requiring fixes), rather than relying on a single solution being applied
to the AST (if any). This lets us produce unresolved member completions even
when the contextual type is ambiguous or involves errors.
Whenever typeCheckExpression is called on an expression containing a code
completion expression and a CompletionCallback has been set, each solution
formed is passed to the callback so the type of the completion expression can
be extracted and used to lookup up the members to return.
In the single-element case, it is treated as the dictionary key.
func takesDict(_ x: [Int: String]) {}
takesDict([]) // diagnose with fixit to add missing ':'
takesDict([1]) // diagnose with fixit to add missing ': <#value#>'
takesDict([foo.<complete>]) // prioritise Int members in completion results -
// the user just hasn't written the value yet.
The above previously failed with a generic mismatch error in normal type
checking (due to the literal being parsed as an array literal) and code
completion could not pick up the expected type from the context.
Using canonical types. Otherwise 'Optional<T>' and 'T?' aren't
considered the same.
Also, for example, the expected context types are 'T?' and 'T', don't
get results from 'T' twice.
rdar://problem/71063455
If access of the target type is 'private', derived hash(into:) used to
be created with 'private' access. But it should be 'fileprivate'.
rdar://problem/71005827
In -batch-code-completion mode, add a token parameter 'xfail={reason}'.
When 'FileCheck' succeeds on the token, it is considered "unexpected
pass", and the test fails.
rdar://problem/71021285
struct Point { var x, y: Int }
protocol P {}
extension P {
subscript<T>(dynamicMember key: KeyPath<Point, T>) -> T
}
@dynamicMemberLookup struct S: P {}
S().<HERE>
Previously, completion couldn't suggest 'x' and 'y'. Include
'NL_ProtocolMembers' when finding 'subscript(dynamicMember:)'.
rdar://problem/71008072
Just adding a test case since it's already fixed.
Until d78bf22413, if there are multiple
brace statements in an ASTNode, only the first brace statement is
considered to be type checked.
rdar://problem/71001317
Similar to 4cf7426698 but for the case
when the completion is in a default argument expression rather than
initializer. Fixed to grab either the initializer or default argument if
there is one.
Strings are a single token, so the previous check would treat
completions inside string interpolations as being outside of the
initializer.
Grab the end of the token from the Lexer, but wrap in a context check to
avoid performing that for every declaration found in the lookup.
Resolves rdar://70833348
`::lookupVisibleDecls` had an inline consumer in order to remove
"unusable" results. Refactor this method, moving the consumer (now
`UsableFilteringDeclConsumer`) to allow its use when looking up top
level module declarations.
Also use the `AccessFilteringDeclConsumer` in preference to a condition
in `addVarDecl`.
Resolves rdar://56755598
Review over a large number of APIs has found that most of the time, the
result type of an Objective-C completion handler method that becomes
"async throws" should be optional. Change the default behavior to
match this, and replace _Nullable_on_error with _Nullable_result to
capture the case where the result should be optional.
Solver-based member completion performs a lookup per solution, but if the base
types in each solution are variations of the same generic (e.g. Array<Int>,
Array<String>), we can end up with the same result appearing twice (e.g. count)
"Function builders" are being renamed to "result builders". Add the
corresponding `@resultBuilder` attribute, with `@_functionBuilder` as
an alias for it, Update test cases to use @resultBuilder.
func foo(a: Int, b: Int) {}
func foo(a: String) {}
// Int and String should both be valid, despite the missing argument for the
// first overload since the second arg may just have not been written yet.
foo(a: <complete here>
func bar(a: (Int) -> ()) {}
func bar(a: (String, Int) -> ()) {}
// $0 being of type String should be valid, rather than just Int, since $1 may
// just have not been written yet.
bar { $0.<complete here> }
...and adjust the fallback context it choses now that ErrorExprs no longer
cause constraint generation to fail.
Also fix some issues with the fallback logic in typeCheckForCodeCompletion:
1) For completion expressions in multi-statement closures, we were assuming a
separate typeCheckExpression call would be made when the outer expression
produced a single solution that had a resolved type for the closure. If the
solution contained other fixes unrelated to the closure however, it wasn't
applied and a separate call for the body was never made.
2) typeCheckForCodeComplation sometimes falls back to regular expression type
checking but didn't update the passed-in target's expression after santizing
and prechecking it, which may have modified it and its sub-expressions. This
triggered assertion failures in certain cases due to the mix of the stale
top-level expression pointer being used with updated subexpressions.