Note: This is in reverse chronological order, so newer entries are added to the top.
- With the introduction of the new
SwiftParser
, the existingSwiftSyntaxParser
is deprecated and will be removed. The module and it's API surface still exists as a thin wrapper overSwiftParser
, which no longer requires a matching toolchain or_InternalSwiftSyntaxParser
shared library to work.
-
To clarify that the edits passed to
IncrementalParseTransition
are applied concurrently, introduce a newConcurrentEdit
type that provides the guarantee and allows translation of sequentially applied edits to the expected concurrent form. -
The
SwiftSyntaxParser
type and a few related types now live in their own module (also namedSwiftSyntaxParser
). This allows usingSwiftSyntax
for code generation purposes without having a compatible_InternalSwiftSyntaxParser.dylib
around.import SwiftSyntaxParser
where necessary. -
DiagnosticEngine
has been removed. Instead,SyntaxParser
takes a closure through which it emits parser diagnostics. Depending on your needs, use the closure to handle the diagnostics or write + hook up your own diagnostics engine.
-
Introduced
FunctionCallExprSyntax.additionalTrailingClosures
property with typeMultipleTrailingClosureElementListSyntax?
for supporting SE-0279 Multiple Trailing Closures. -
Introduced
syntaxNodeType
property for all types conforming toSyntaxProtocol
, which returns the underlying syntax node type. It is primarily intended as a debugging aid during development. -
Provided a clearer error message for the "parser compatibility" error.
-
ReversedSyntaxChildren
has been removedUse the
reversed()
property onSyntaxCollection
, which now conforms toBidirectionalCollection
instead. -
SyntaxCollection
s now conform toBidirectionalCollection
The previous conformance to
Sequence
has been upgraded to a conformance toBidirectionalCollection
-
Properties
isExpr
,isDecl
,isStmt
,isType
andisPattern
removed fromSyntaxNode
Use
is(ExprSyntaxProtocol.self)
etc. instead. -
Property
uniqueIdentifier
removed from syntax nodes andSyntaxNode
Use the newly added property
id
or the conformance toIdentifiable
instead. -
Syntax nodes and
SyntaxNode
conform toIdentifiable
Identifiable
conformance has been added to all syntax nodes and theSyntaxNode
type usingSyntaxIdentifier
as the identifier. -
The
walk
method on syntax nodes has been removed.Instead, use the
walk
method on theSyntaxVisitor
.// Before tree.walk(&visitor) // Now visitor.walk(tree)
-
SyntaxVisitor
andSyntaxAnyVisitor
are aclass
and no longer aprotocol
.For performance reasons the
SyntaxVisitor
andSyntaxAnyVisitor
were migrated from being a protocol to being a class.Any structs conforming to the above protocols need to become classes. Implementing methods need to be marked
override
and, if necessary, anymutating
keywords need to be removed.// Before struct Visitor: SyntaxVisitor { mutating func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { /* ... */ } } // Now class Visitor: SyntaxVisitor { override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { /* ... */ } }
-
A new type
SyntaxEnum
has been introducedThe new type
SyntaxEnum
allow exhaustive switching over all syntax types. It can be constructed by callingasSyntaxEnum
onSyntax
.let node: Syntax switch node.as(SyntaxEnum.self) { case .identifierExpr(let identifierExprSyntax): /* ... */ }
For increased performance, the modelling of the syntax node hierarchy has been switched from being protocol
-based to being struct
-based. This includes the following changes:
-
The protocols
ExprSyntax
,DeclSyntax
,Syntax
etc. have been removedFor passing values of these types around, use the new type erasers
ExprSyntax
,DeclSyntax
,Syntax
etc. instead. To add computed properties or functions to all expression nodes, write an extension onExprSyntaxProtocol
. To add methods to all syntax nodes, extendSyntaxProtcol
.Pass type eraser
func foo(_ expr: ExprSyntax) {}
stays the same.
ExprSyntax
is now a struct and not a protocol. See below on how to create anExprSyntax
.Extending a type
// Before extension ExprSyntax { func evaluateAsIntegerExpr() -> Int { /* ... */ } } // Now extension ExprSyntaxProtocol { func evaluateAsIntegerExpr() -> Int { /* ... */ } }
-
Checking a node's type can no longer be performed using the
is
operator. Use theis(_: SyntaxProtocol)
method on any type eraser instead.// Before exprSyntax is IdentifierExprSyntax // Now exprSyntax.is(IdentifierExprSyntax.self)
-
To retrieve the non-type erased version of a type, use the
as(_: SyntaxProtocol.self)
methodlet identifierExprSyntax: IdentifierExprSyntax = /* ... */ let node = Syntax(identifierExprSyntax) node.asProtocol(SyntaxProtocol.self) // returns an IdentifierExprSyntax with static type SyntaxProtocol node.asProtocol(ExprSyntaxProtocol.self) // returns an IdentifierExprSyntax with static type ExprSyntaxProtocol?
-
Downcasting can no longer be performed using the
as
operator. For downcasting use theas(_: SyntaxProtocol)
method on any type eraser.// Before exprSyntax as? IdentifierExprSyntax // Now exprSyntax.as(IdentifierExprSyntax.self)
-
Upcasting needs to be performed explicitly. Use the designated initializers for this.
// Before func foo() -> ExprSyntax { /* ... */ return identiferExprSyntax } // Now func foo() -> ExprSyntax { /* ... */ return ExprSyntax(identiferExprSyntax) }