diff --git a/Sources/SwiftSyntax/SyntaxBaseNodes.swift.gyb b/Sources/SwiftSyntax/SyntaxBaseNodes.swift.gyb index c874304913a..faef5ef274c 100644 --- a/Sources/SwiftSyntax/SyntaxBaseNodes.swift.gyb +++ b/Sources/SwiftSyntax/SyntaxBaseNodes.swift.gyb @@ -51,6 +51,7 @@ public extension Syntax { public struct ${node.name}: ${node.name}Protocol, SyntaxHashable { public let _syntaxNode: Syntax + /// Create a `${node.name}` node from a specialized syntax node. public init(_ syntax: S) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get @@ -58,6 +59,12 @@ public struct ${node.name}: ${node.name}Protocol, SyntaxHashable { self.init(syntax._syntaxNode.data) } + /// Create a `${node.name}` node from a specialized optional syntax node. + public init?(_ syntax: S?) { + guard let syntax = syntax else { return nil } + self.init(syntax) + } + /// Converts the given `Syntax` node to a `${node.name}` if possible. Returns /// `nil` if the conversion is not possible. public init?(_ syntax: Syntax) { diff --git a/Sources/SwiftSyntax/gyb_generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/gyb_generated/SyntaxBaseNodes.swift index a29b53fe15b..d5294809ccb 100644 --- a/Sources/SwiftSyntax/gyb_generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/gyb_generated/SyntaxBaseNodes.swift @@ -38,6 +38,7 @@ public extension Syntax { public struct DeclSyntax: DeclSyntaxProtocol, SyntaxHashable { public let _syntaxNode: Syntax + /// Create a `DeclSyntax` node from a specialized syntax node. public init(_ syntax: S) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get @@ -45,6 +46,12 @@ public struct DeclSyntax: DeclSyntaxProtocol, SyntaxHashable { self.init(syntax._syntaxNode.data) } + /// Create a `DeclSyntax` node from a specialized optional syntax node. + public init?(_ syntax: S?) { + guard let syntax = syntax else { return nil } + self.init(syntax) + } + /// Converts the given `Syntax` node to a `DeclSyntax` if possible. Returns /// `nil` if the conversion is not possible. public init?(_ syntax: Syntax) { @@ -135,6 +142,7 @@ public extension Syntax { public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { public let _syntaxNode: Syntax + /// Create a `ExprSyntax` node from a specialized syntax node. public init(_ syntax: S) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get @@ -142,6 +150,12 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { self.init(syntax._syntaxNode.data) } + /// Create a `ExprSyntax` node from a specialized optional syntax node. + public init?(_ syntax: S?) { + guard let syntax = syntax else { return nil } + self.init(syntax) + } + /// Converts the given `Syntax` node to a `ExprSyntax` if possible. Returns /// `nil` if the conversion is not possible. public init?(_ syntax: Syntax) { @@ -232,6 +246,7 @@ public extension Syntax { public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable { public let _syntaxNode: Syntax + /// Create a `StmtSyntax` node from a specialized syntax node. public init(_ syntax: S) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get @@ -239,6 +254,12 @@ public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable { self.init(syntax._syntaxNode.data) } + /// Create a `StmtSyntax` node from a specialized optional syntax node. + public init?(_ syntax: S?) { + guard let syntax = syntax else { return nil } + self.init(syntax) + } + /// Converts the given `Syntax` node to a `StmtSyntax` if possible. Returns /// `nil` if the conversion is not possible. public init?(_ syntax: Syntax) { @@ -329,6 +350,7 @@ public extension Syntax { public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { public let _syntaxNode: Syntax + /// Create a `TypeSyntax` node from a specialized syntax node. public init(_ syntax: S) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get @@ -336,6 +358,12 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable { self.init(syntax._syntaxNode.data) } + /// Create a `TypeSyntax` node from a specialized optional syntax node. + public init?(_ syntax: S?) { + guard let syntax = syntax else { return nil } + self.init(syntax) + } + /// Converts the given `Syntax` node to a `TypeSyntax` if possible. Returns /// `nil` if the conversion is not possible. public init?(_ syntax: Syntax) { @@ -426,6 +454,7 @@ public extension Syntax { public struct PatternSyntax: PatternSyntaxProtocol, SyntaxHashable { public let _syntaxNode: Syntax + /// Create a `PatternSyntax` node from a specialized syntax node. public init(_ syntax: S) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get @@ -433,6 +462,12 @@ public struct PatternSyntax: PatternSyntaxProtocol, SyntaxHashable { self.init(syntax._syntaxNode.data) } + /// Create a `PatternSyntax` node from a specialized optional syntax node. + public init?(_ syntax: S?) { + guard let syntax = syntax else { return nil } + self.init(syntax) + } + /// Converts the given `Syntax` node to a `PatternSyntax` if possible. Returns /// `nil` if the conversion is not possible. public init?(_ syntax: Syntax) { diff --git a/Tests/SwiftSyntaxTest/SyntaxTests.swift b/Tests/SwiftSyntaxTest/SyntaxTests.swift index 92ed527bd3c..40ac0921a29 100644 --- a/Tests/SwiftSyntaxTest/SyntaxTests.swift +++ b/Tests/SwiftSyntaxTest/SyntaxTests.swift @@ -119,5 +119,8 @@ public class SyntaxTests: XCTestCase { case .integerLiteralExpr: break default: XCTFail("failed to convert to SyntaxEnum") } + + XCTAssertNil(ExprSyntax(nil as IntegerLiteralExprSyntax?)) + XCTAssertEqual(ExprSyntax(integerExpr).as(IntegerLiteralExprSyntax.self)!, integerExpr) } }