Commit Graph

6321 Commits

Author SHA1 Message Date
Alex Hoppen
282cbc3590 Merge pull request #36930 from ahoppen/pr/complete-switch-expr-in-closure
[Parse] Create SwitchStmt nodes for `switch` statements with errors
2021-04-16 10:44:00 +02:00
Kavon Farvardin
4f6eb85fe3 allow type initializers to be 'async'
implicit calls to an async super.init are not allowed
2021-04-15 10:08:53 -07:00
Alex Hoppen
931f3394d7 [Parse] Create SwitchStmt nodes for switch statements with errors
At the moment, if there is an error in the `switch` statement expression or if the `{` is missing, we return `nullptr` from `parseStmtSwitch`, but we consume tokens while trying to parse the `switch` statement. This causes the AST to not contain any nodes for the tokens that were consumed while trying to parse the `switch` statement.

While this doesn’t cause any issues during compilation (compiling fails anyway so not having the `switch` statement in the AST is not a problem) this causes issues when trying to complete inside an expression that was consumed while trying to parse the `switch` statement but doesn’t have a representation in the AST. The solver-based completion approach can’t find the expression that contains the completion token (because it’s not part of the AST) and thus return empty results.

To fix this, make sure we are always creating a `SwitchStmt` when consuming tokens for it.

Previously, one could always assume that a `SwitchStmt` had a valid `LBraceLoc` and `RBraceLoc`. This is no longer the case because of the recovery. In order to form the `SwitchStmt`’s `SourceRange`, I needed to add a `EndLoc` property to `SwitchStmt` that keeps track of the last token in the `SwitchStmt`. Theoretically we should be able to compute this location by traversing the right brace, case stmts, subject expression, … in reverse order until we find something that’s not missing. But if the `SubjectExpr` is an `ErrorExpr`, representing a missing expression, it might have a source range that points to one after the last token in the statement (this is due to the way the `ErrorExpr` is being constructed), therefore returning an invalid range. So overall I thought it was easier and safer to add another property.

Fixes rdar://76688441 [SR-14490]
2021-04-15 18:37:25 +02:00
Alex Hoppen
4603b6753b [CodeComplete] Fix issue completing type in generic signature
Due to https://github.com/apple/swift/pull/36552, parsing the code completion token as a type inside a generic parameter list no longer fails. Instead, it consumes the code completion token as a type identifier. However, since `parseExprIdentifer` does not return a `ParserStatus`, the information whether a code completion token was consumed gets lost, causing `setCodeCompletionDelayedDeclState` to not be called and thus no code completion results show up.

To resolve this, make `parseExprIdentifier` return its `ParserStatus` through a `ParserResult`.

Fixes rdar://76335452 [SR-14432]
2021-04-12 18:45:00 +02:00
Alex Hoppen
5cf19e4570 Merge pull request #36646 from ahoppen/pr/verify-syntax-tree-build-swift
[libSyntax] Several fixes for libSyntax parsing
2021-04-12 10:07:32 +02:00
Alex Hoppen
a98173baa2 [libSyntax] Several fixes for libSyntax parsing
Fixe a couple of bugs in libSyntax parsing found by enabling `-verify-syntax-tree` for `%target-build-swift`:
- Fix parsing of the `actor` contextual keyword in actor decls
- Don't build a libSyntax tree when parsing the availability macro
  - The availability macro is not part of the source code and doesn't form a valid Swift file, thus creation of a libSyntax tree is completely pointless and will fail
- Add support for parsing `@_originallyDefinedIn` attributes.
- Add support for parsing `#sourceLocation` in member decl lists
- Add support for effectful properties (throwing/async getters/setters)
- Add support for optional types as the base of a key path (e.g. `\TestOptional2?.something`)
- Allow platform restrictions without a version (e.g. `_iOS13Aligned`)
2021-04-09 14:16:51 +02:00
Alex Hoppen
294977534c [libSyntax] Remove incremental JSON transfer option
We were only keeping track of `RawSyntax` node IDs to incrementally transfer a syntax tree via JSON. However, AFAICT the incremental JSON transfer option has been superceeded by `SyntaxParseActions`, which are more efficient.

So, let’s clean up and remove the `RawSyntax` node ID and JSON incremental transfer option.

In places that still need a notion of `RawSyntax` identity (like determining the reused syntax regions), use the `RawSyntax`’s pointer instead of the manually created ID.

In `incr_transfer_round_trip.py` always use the code path that uses the `SyntaxParseActions` and remove the transitional code that was still using the incremental JSON transfer but was never called.
2021-04-07 10:01:34 +02:00
Nathan Hawes
927c709a50 Merge pull request #36738 from nathawes/fix-completion-crash
[CodeCompletion][Parse] Don't drop the contained expression when completing within an InOutExpr
2021-04-06 15:54:44 +10:00
Slava Pestov
c9f550c60f Parse: Parse an explicit 'nil' default argument as DefaultArgumentKind::NilLiteral
We support a special DefaultArgumentKind::NilLiteral, but it was only
used for synthesized and imported default arguments as well.

Let's also use it for parsed default arguments that are exactly 'nil',
so that rethrows checking can special-case them.
2021-04-02 23:56:59 -04:00
Nathan Hawes
b8f5bf3434 [CodeCompletion][Parse] Don't drop the contained expression when completing within an InOutExpr
When completing within an InOutExpr like `&foo.<complete>`, we were forming a
CodeCompletionExpr with a base when parsing the content of the InOutExpr and
storing it in CodeCompletionCallbacksImpl::CodeCompleteTokenExpr. When the
result of that parse contained a code completion though, we were dropping the
sub-expression completely and forming an empty code completion result in place
of the inout expression, which resulted in later code inserting a code
completion expression with no base into the AST. The solver based completion
was later asking for the type of the code completion and its base using the
expression stored in CodeCompletionCallbacksImpl::CodeCompleteTokenExpr, but
that never ended up in the AST so we hit an assertion about the expression not
have a type in the formed solutions.

Resolves rdar://75366814
2021-04-03 13:39:23 +10:00
Kavon Farvardin
f9452b23f4 implement parsing for effects specifiers on 'get' accessors
An effectful 'get' accessor must be the only accessor for the
property.
2021-03-26 07:54:53 -07:00
Becca (née Brent) Royal-Gordon
3df5ca6636 Merge pull request #36409 from beccadax/behave-yourself
Soften errors for invalid @objc attributes added by access notes
2021-03-25 15:44:22 -07:00
Becca Royal-Gordon
e22b6d6ee4 Handle subscripts in formDeclNameRef()
In particular, we were unconditionally dropping argument labels on accessors; now we only do that for property accessors, not subscript accessors.

Doing this unconditionally causes ClangImporter failures when a method parameter is called “subscript” (really!), so this behavior is enabled only by the caller’s request.
2021-03-24 14:55:06 -07:00
Alex Hoppen
695c725f1e [CodeComplete] Return true from canParseType if type contains code completion token
From my point of view, a type that contains a code completion token can still be parsed as a type and as such, `canParseType` should return `true` for e.g. `#^COMPLETE^#` or `SomeType.#^COMPLETE^#`.

Changing this fixes an issue that caused no type completions to be shown inside a enum case decl.

Fixes rdar://71984715
2021-03-23 15:02:26 +01:00
Alex Hoppen
e0fca6c12f Merge pull request #36491 from ahoppen/pr/rdar64304839
[SourceKit] Fix crash in syntax model
2021-03-22 12:18:08 +01:00
Alex Hoppen
5d9163598a [SourceKit] Fix crash in syntax model
The end location of an attribute used to point to the next token after the attribute's content, which is the closing parenthesis in valid Swift code. But when the parenthesis is missing, it points to the next token, which is most likely no longer part of the attribute.

Fix by parsting the closing parenthesis (conditionally) first and using the location of last token parsed for the attribute (`PreviuosLoc`) as the attribute range's end location.

Resolves rdar://64304839
2021-03-19 13:12:03 +01:00
Doug Gregor
52096a640e SE-0302: Rename ConcurrentValue/@concurrent to Sendable/@Sendable. 2021-03-18 23:48:21 -07:00
Doug Gregor
5eea13e32b Improve closure lookahead for custom attributes 2021-03-17 00:51:58 -07:00
Doug Gregor
09d7f47d31 Fix code completion for custom attributes. 2021-03-16 19:52:16 -07:00
Doug Gregor
f7800fde31 Propagate parsed type attributes to TypeAttributes.
Propagate parsed type attributes to the TypeAttributes structure, so they
persist in the AST and can be processed by the type checker. Move the
"unknown attribute" diagnostic for custom attributes on types into
the type checker.
2021-03-16 19:52:16 -07:00
Doug Gregor
7f6b681ced [Parser] Parse custom attributes on types.
Extend the parsing of custom attributes to apply to types. Improve the
lookahead for the arguments so we don't arbitrarily consume the parameter
list of a function type as an attribute argument, or consume a tuple type
as the attribute argument.

Doesn't actually change behavior, because after parsing the custom
attribute on a type, we reject it as an unknown attribute.
2021-03-16 19:52:05 -07:00
Alex Hoppen
fece895cb9 Merge pull request #36417 from ahoppen/pr/libsyntax-performance-improvements
[libSyntax] Several small improvements to libSyntax parsing
2021-03-16 23:53:22 +01:00
Evan Wilde
eaab395973 Remove ExplicitCompletionHandlerIndex flag
Assuming that we don't typecheck a deserialized module, we don't
actually need the ExplicitCompletionHandlerIndex. We used this flag to
determine whether we could trust the number stored in the handler index
or just take the last parameter of the function we're attached to.

Since we only typecheck it before serialization, we can safely check
that the completion handler location is valid before choosing whether we
should trust it or not.
2021-03-13 13:38:15 -08:00
Evan Wilde
2b0def501f Replace @hasAsyncAlt with @completionHandlerAsync
This patch replaces the @hasAsyncAlternative attribute with
@completionHandlerAsync. The @completionHandlerAsync attribute takes the
function decl name of the async function and optionally the index of the
completion hander parameter in the function that it's attached to.
If the completion handler index is not provided, it's assumed to be the
last parameter in the parameter list.

We resolve the async function while typechecking the attribute. Before
resolving, we verify that the function the attribute is attached to
isn't async, that it has enough parameters to at least have the
indicated completion handler referenced by the index, that the
completion handler is an escaping non-auto-closure function that returns
Void.

The async function declaration resolution isn't perfect yet, but I want
to get this patch up and we can refine it later. It pulls all of the
delcs with the specified declname in the same context as the
function that the attribute is attached to. Going through that list, it
keeps any that are async functions. If there are none, we emit an error
saying that there are no viable functions, if there are multiple we emit
an error saying that the decl name is ambiguous, and if there is one
function, we keep that as the resolve async function declaration.

This does not take into account the data types of the completion handler
or the async function. There are some complexities to making this
mapping. Here are the pieces:
 - If the completion handler takes a single data type, the async
   function should return that type. (easy case)
 - If the completion handler takes a `Result<T, Error>`, the async
   function is a throwing function that returns a T. (Medium difficulty)
 - If the completion handler looks like `(T?, Error?) -> Void`, we have
   an ambiguous situation between the following async functions:
   - func foo() async throws -> T
   - func foo() async throws -> T?
   That is, we cannot tell whether the `T?` in the completion handler is
   optional because it will be nil on an error, or if it is intended to
   be optional.

This can be done later if it becomes a problem.
2021-03-13 13:38:15 -08:00
Alex Hoppen
b20683252b [libSyntax] Eliminate loop and memory allocation translating ParsedRawSyntaxNode to RecordedOrDeferredNode 2021-03-12 08:47:08 +01:00
Alex Hoppen
a7703566e9 [libSyntax] Inline commonly called methods in ParsedRawSyntaxRecorder 2021-03-12 08:46:54 +01:00
Alex Hoppen
f7410ff0e7 Merge pull request #36385 from ahoppen/pr/no-range-in-parsedrawsyntaxnode
[libSyntax] Only keep track of range in ParsedRawSyntaxNode if verifying element ranges
2021-03-12 08:16:56 +01:00
Alex Hoppen
350ac1514c [libSyntax] Only keep track of range in ParsedRawSyntaxNode if verifying element ranges
This makes ParsedRawSyntaxNode a zero-cost wrapper around RecordedOrDeferredNode in the case that ranges are not verified.
2021-03-11 19:58:59 +01:00
Alex Hoppen
bfbd812a21 [Parser] Distinguish between backtracking scopes that can be cancelled or not
For backtracking scopes that are never cancelled, we can completely disable the SyntaxParsingContext, avoiding the creation of deferred nodes which will never get recorded.
2021-03-10 17:29:33 +01:00
Alex Hoppen
0d913e9531 Merge pull request #36364 from ahoppen/pr/deferred-rawsyntax-nodes
[libSyntax] Don't create dedicated deferred nodes in SyntaxTreeCreator
2021-03-10 15:20:26 +01:00
Alex Hoppen
a47bd7089e [libSyntax] Don't create dedicated deferred nodes in SyntaxTreeCreator
We have finally reached our goal of optimising deferred node creation
for SyntaxTreeCreator. Instead of creating dedicated deferred nodes and
copying the data into a RawSyntax node when recording, we always create
RawSyntax nodes. Recording a deferred node is thus a no-op, since we
have already created a RawSyntax node. Should a deferred node not be
recorded, it stays alive in the SyntaxArena without any reference to it.
While this means, we are leaking some memory for such nodes, most nodes
do get recorded, so the overhead should be fine compared to the
performance benefit.
2021-03-10 08:48:18 +01:00
Alex Hoppen
c13cf2c21c [libSyntax] Remove ParsedRawSyntaxNode::copyDeferred
This is no longer needed.
2021-03-09 23:01:49 +01:00
Alex Hoppen
bf6aff9f7e [libSyntax] Allow retrieval of a null child from deferred ParsedRawSyntaxNodes 2021-03-09 19:10:25 +01:00
Alex Hoppen
e6da01b912 [libSyntax] Remove getData method from ParsedRawSyntaxNode
The getData and getRecordedOrDeferredNode methods broke the move-only semantics of ParsedRawSyntaxNode because it allowed retrieving the data without resetting it.

Change most uses to use takeData or takeRecordedOrDeferredNode instead of the get methods.

To retrieve the children of a ParsedRawSyntaxNode, we still need a way to access the OpaqueSyntaxNode for inspection by the SyntaxParseActions without resetting it. For this, we still maintain a method with the semantics of getData, but it’s now called getUnsafeOpaqueData to make sure it’s not accidentally used.
2021-03-09 19:10:25 +01:00
Alex Hoppen
a38dc1aa60 [libSyntax] Remove unnecessary getOpaqueNode and takeOpaqueNode from ParsedRawSyntaxNode
They are superseded by getData/takeData
2021-03-09 14:26:08 +01:00
Alex Hoppen
439b44b365 [libSyntax] Re-enable dumping of ParsedRawSyntaxNode children
This requires a SyntaxParsingContext to be passed to the dump function
and was thus disabled in an earlier commit
2021-03-09 14:26:08 +01:00
Alex Hoppen
c8acecd15d [libSyntax] Store DataKind and OpaqueSyntaxNode in ParsedRawSyntaxNode as RecordedOrDeferredNode
This is mostly a clean-up commit. ParsedRawSyntaxNode stores an
OpaqueSyntaxNode and its DataKind so it might as well use a
RecordedOrDeferredNode.
2021-03-09 14:26:08 +01:00
Alex Hoppen
efb91f70a1 [libSyntax] Handle deferred node data in SyntaxParseActions
By now ParsedRawSyntaxNode does not have any knowledge about deferred
node data anymore, which frees up SyntaxParseActions (and, in
particular its sublass SyntaxTreeCreator) to perform optimisations to
more efficiently create and record deferred nodes.
2021-03-09 14:26:08 +01:00
Alex Hoppen
a5632b4836 [libSyntax] Create DeferredLayoutNode/DeferredTokenNode in ParsedRawSyntaxRecorder
This is an intermediate step in the effort to push deferred node
handling all the way down to SyntaxParseActions.
2021-03-09 14:26:08 +01:00
Alex Hoppen
26dc01b37c Merge pull request #36274 from ahoppen/pr/range-in-parsedrawsyntaxnode
[libSyntax] Store Range of ParsedRawSyntaxNode in dedicated field
2021-03-08 10:21:04 +01:00
Alex Hoppen
7be748dbda [libSyntax] Store Range of ParsedRawSyntaxNode in dedicated field
Essentially all ParsedRawSyntaxNode types have a range associated with
them, so let's just store it in a dedicated field with a common getter.

Additionally, this cleans up the recorded storage to just contain an
OpaqueSyntaxNode. When deferred nodes are being handled by
SyntaxParseActions, we can use this OpaqueNode storage to store either
recorded or deferred node data, which is left to be interpreted by the
SyntaxParseAction.
2021-03-05 14:43:11 +01:00
Alex Hoppen
bde8224f73 Merge pull request #36230 from ahoppen/pr/ref-count-syntaxdata
[libSyntax] Reference count SyntaxData
2021-03-05 14:31:49 +01:00
Slava Pestov
375d246263 Merge pull request #36176 from slavapestov/reasync-call-site-checking
Implementing checking for 'reasync' call sites
2021-03-04 18:37:38 -05:00
Alex Hoppen
ef485d405e [libSyntax] Create deferred nodes in the ParsedRawSyntaxRecorder
This is a multi-commit effort to push the responsibility of deferred
node handling to the SyntaxParseActions which have more detailed
knowledge of their requirements on deferred nodes and might perform
additional optimisations. For example, the SyntaxTreeCreator can always
create RawSyntax nodes (even for deferred nodes) and decide to simply
not use them, should the deferred nodes not get recorded.
2021-03-03 08:49:59 +01:00
Alex Hoppen
56a923475f [libSyntax] Reference count SyntaxData
Instead of having a heap-allocated RefCountedBox to store a SyntaxData's
parent, reference-count SyntaxData itself. This has a couple of
advantages:
 - When passing SyntaxData around, only a pointer needs to be passed
   instead of the entire struct contents. This is faster.
 - We can later introduce a SyntaxDataRef, which behaves similar to
   SyntaxData, but delegates the responsibility that the parent stays
   alive to the user. While sacrificing guaranteed memory safety, this
   means that SyntaxData can then be stack-allocated without any
   ref-counting overhead.
2021-03-03 08:48:24 +01:00
Alex Hoppen
68877f987f Merge pull request #36229 from ahoppen/pr/opaque-const-pointer-and-delete-discarednode
[libSyntax] Miscellaneous minor improvements
2021-03-03 08:36:47 +01:00
Alex Hoppen
d35017bc21 Merge pull request #36237 from ahoppen/pr/pass-token-to-tokenreceiver
[Parser] Pass token to TokenReceiver by reference
2021-03-03 08:27:46 +01:00
Alex Hoppen
dc8eed4279 [libSyntax] Delete discardRecordedNode
It doesn't do anything anymore and we shouldn't have it, so let's just
remove it.
2021-03-02 20:07:26 +01:00
Alex Hoppen
961d32d517 [Parser] Pass token to TokenReceiver by reference
Small peformance improvement: Token is larger than a pointer and not
modified in the performance-criticial TokenReceivers, so we can pass
it by reference.
2021-03-02 18:33:08 +01:00
Alex Hoppen
96cb75608c Merge pull request #36165 from ahoppen/pr/dont-ref-count-rawsyntax
[libSyntax] Don't reference count RawSyntax
2021-03-02 17:40:17 +01:00