Note: This is in reverse chronological order, so newer entries are added to the top.
- With the introduction of the new
SwiftParser, the existingSwiftSyntaxParseris 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_InternalSwiftSyntaxParsershared library to work.
-
To clarify that the edits passed to
IncrementalParseTransitionare applied concurrently, introduce a newConcurrentEdittype that provides the guarantee and allows translation of sequentially applied edits to the expected concurrent form. -
The
SwiftSyntaxParsertype and a few related types now live in their own module (also namedSwiftSyntaxParser). This allows usingSwiftSyntaxfor code generation purposes without having a compatible_InternalSwiftSyntaxParser.dylibaround.import SwiftSyntaxParserwhere necessary. -
DiagnosticEnginehas been removed. Instead,SyntaxParsertakes 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.additionalTrailingClosuresproperty with typeMultipleTrailingClosureElementListSyntax?for supporting SE-0279 Multiple Trailing Closures. -
Introduced
syntaxNodeTypeproperty 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.
-
ReversedSyntaxChildrenhas been removedUse the
reversed()property onSyntaxCollection, which now conforms toBidirectionalCollectioninstead. -
SyntaxCollections now conform toBidirectionalCollectionThe previous conformance to
Sequencehas been upgraded to a conformance toBidirectionalCollection -
Properties
isExpr,isDecl,isStmt,isTypeandisPatternremoved fromSyntaxNodeUse
is(ExprSyntaxProtocol.self)etc. instead. -
Property
uniqueIdentifierremoved from syntax nodes andSyntaxNodeUse the newly added property
idor the conformance toIdentifiableinstead. -
Syntax nodes and
SyntaxNodeconform toIdentifiableIdentifiableconformance has been added to all syntax nodes and theSyntaxNodetype usingSyntaxIdentifieras the identifier. -
The
walkmethod on syntax nodes has been removed.Instead, use the
walkmethod on theSyntaxVisitor.// Before tree.walk(&visitor) // Now visitor.walk(tree)
-
SyntaxVisitorandSyntaxAnyVisitorare aclassand no longer aprotocol.For performance reasons the
SyntaxVisitorandSyntaxAnyVisitorwere 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
overrideand, if necessary, anymutatingkeywords 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
SyntaxEnumhas been introducedThe new type
SyntaxEnumallow exhaustive switching over all syntax types. It can be constructed by callingasSyntaxEnumonSyntax.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,Syntaxetc. have been removedFor passing values of these types around, use the new type erasers
ExprSyntax,DeclSyntax,Syntaxetc. 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.
ExprSyntaxis 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
isoperator. 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 a IdentifierExprSyntax with static type SyntaxProtocol node.asProtocol(ExprSyntaxProtocol.self) // returns a IdentifierExprSyntax with static type ExprSyntaxProtocol?
-
Downcasting can no longer be performed using the
asoperator. 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) }