From 12993b0cec678a061f192a5a96408099b41f3e90 Mon Sep 17 00:00:00 2001 From: Ben Barham Date: Mon, 23 Oct 2023 17:29:51 -0700 Subject: [PATCH] Casts to children of SyntaxProtocol are not always invalid Update these overrides so they don't always fail. --- .../swiftsyntax/SyntaxBaseNodesFile.swift | 55 ++-- Sources/SwiftSyntax/SyntaxProtocol.swift | 2 +- .../generated/SyntaxBaseNodes.swift | 275 +++++++++--------- 3 files changed, 163 insertions(+), 169 deletions(-) diff --git a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift index 85e24463122..f3dcccb9005 100644 --- a/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift +++ b/CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift @@ -71,6 +71,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// Force-casts the current syntax node to a given specialized syntax type. /// /// - Returns: An instance of the specialized type. + /// /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! @@ -79,9 +80,6 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// Checks if the current syntax node can be upcast to its base node type (``\#(node.kind.syntaxType)``). /// /// - Returns: `true` since the node can always be upcast to its base node. - /// - /// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning - /// informing the user that the upcast will always succeed. @available(*, deprecated, message: "This cast will always succeed") public func `is`(_ syntaxType: \#(node.kind.syntaxType).Type) -> Bool { return true @@ -90,9 +88,6 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// Attempts to upcast the current syntax node to its base node type (``\#(node.kind.syntaxType)``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `\#(node.kind.syntaxType).init` for upcasting") public func `as`(_ syntaxType: \#(node.kind.syntaxType).Type) -> \#(node.kind.syntaxType)? { return \#(node.kind.syntaxType)(self) @@ -101,46 +96,50 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// Force-upcast the current syntax node to its base node type (``\#(node.kind.syntaxType)``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `\#(node.kind.syntaxType).init` for upcasting") public func cast(_ syntaxType: \#(node.kind.syntaxType).Type) -> \#(node.kind.syntaxType) { return \#(node.kind.syntaxType)(self) } - /// Checks if the current syntax node can be cast to a given node type from the different base node protocol hierarchy than ``\#(node.kind.protocolType)``. + /// Checks if the current syntax node can be cast to a given node type from a base node protocol hierarchy other + /// than ``\#(node.kind.protocolType)``. /// - /// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``\#(node.kind.protocolType)``. + /// - Returns: `true` if the node can be cast, `false` otherwise. /// - /// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is comparing a ``\#(node.kind.protocolType)`` to a node that is not a + /// ``\#(node.kind.protocolType)``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``\#(node.kind.protocolType)`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the '\#(node.kind.protocolType)' hierarchy") public func `is`(_ syntaxType: S.Type) -> Bool { - return false + return self.as(syntaxType) != nil } - /// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``\#(node.kind.protocolType)``. + /// Attempts to cast the current syntax node to a given node type from the a base node protocol hierarchy other than + /// ``\#(node.kind.protocolType)``. /// - /// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``\#(node.kind.protocolType)``. + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. /// - /// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``\#(node.kind.protocolType)`` to a node that is not a + /// ``\#(node.kind.protocolType)``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``\#(node.kind.protocolType)`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the '\#(node.kind.protocolType)' hierarchy") public func `as`(_ syntaxType: S.Type) -> S? { - return nil + return S.init(self) } - /// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``\#(node.kind.protocolType)``. + /// Force-casts the current syntax node to a given node type from a base node protocol hierarchy other than + /// ``\#(node.kind.protocolType)``. + /// + /// - Returns: An instance of the specialized type. /// - /// - Returns: This method will always trigger a runtime crash and never return. + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. /// - /// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - /// - Warning: Invoking this method will lead to a fatal error. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``\#(node.kind.protocolType)`` to a node that is not a + /// ``\#(node.kind.protocolType)``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``\#(node.kind.protocolType)`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the '\#(node.kind.protocolType)' hierarchy") public func cast(_ syntaxType: S.Type) -> S { - fatalError("\(Self.self) cannot be cast to \(S.self)") + return self.as(S.self)! } } """# diff --git a/Sources/SwiftSyntax/SyntaxProtocol.swift b/Sources/SwiftSyntax/SyntaxProtocol.swift index 286c7382edd..4959bb84cb4 100644 --- a/Sources/SwiftSyntax/SyntaxProtocol.swift +++ b/Sources/SwiftSyntax/SyntaxProtocol.swift @@ -89,7 +89,7 @@ public extension SyntaxProtocol { return S.init(self) } - /// Attempts to upcast the current syntax node to ``Syntax`` node.. + /// Attempts to upcast the current syntax node to ``Syntax`` node. /// /// - Returns: The ``Syntax`` node created from the current syntax node, as the node can always be upcast to ``Syntax`` node. /// diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index 50479429881..d46e0a2ba60 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -57,6 +57,7 @@ extension DeclSyntaxProtocol { /// Force-casts the current syntax node to a given specialized syntax type. /// /// - Returns: An instance of the specialized type. + /// /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! @@ -66,9 +67,6 @@ extension DeclSyntaxProtocol { /// Checks if the current syntax node can be upcast to its base node type (``DeclSyntax``). /// /// - Returns: `true` since the node can always be upcast to its base node. - /// - /// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning - /// informing the user that the upcast will always succeed. @available(*, deprecated, message: "This cast will always succeed") public func `is`(_ syntaxType: DeclSyntax.Type) -> Bool { return true @@ -78,9 +76,6 @@ extension DeclSyntaxProtocol { /// Attempts to upcast the current syntax node to its base node type (``DeclSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `DeclSyntax.init` for upcasting") public func `as`(_ syntaxType: DeclSyntax.Type) -> DeclSyntax? { return DeclSyntax(self) @@ -90,49 +85,53 @@ extension DeclSyntaxProtocol { /// Force-upcast the current syntax node to its base node type (``DeclSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `DeclSyntax.init` for upcasting") public func cast(_ syntaxType: DeclSyntax.Type) -> DeclSyntax { return DeclSyntax(self) } - /// Checks if the current syntax node can be cast to a given node type from the different base node protocol hierarchy than ``DeclSyntaxProtocol``. + /// Checks if the current syntax node can be cast to a given node type from a base node protocol hierarchy other + /// than ``DeclSyntaxProtocol``. /// - /// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``DeclSyntaxProtocol``. + /// - Returns: `true` if the node can be cast, `false` otherwise. /// - /// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is comparing a ``DeclSyntaxProtocol`` to a node that is not a + /// ``DeclSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``DeclSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'DeclSyntaxProtocol' hierarchy") public func `is`(_ syntaxType: S.Type) -> Bool { - return false + return self.as(syntaxType) != nil } - /// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``DeclSyntaxProtocol``. + /// Attempts to cast the current syntax node to a given node type from the a base node protocol hierarchy other than + /// ``DeclSyntaxProtocol``. /// - /// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``DeclSyntaxProtocol``. + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. /// - /// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``DeclSyntaxProtocol`` to a node that is not a + /// ``DeclSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``DeclSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'DeclSyntaxProtocol' hierarchy") public func `as`(_ syntaxType: S.Type) -> S? { - return nil + return S.init(self) } - /// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``DeclSyntaxProtocol``. + /// Force-casts the current syntax node to a given node type from a base node protocol hierarchy other than + /// ``DeclSyntaxProtocol``. /// - /// - Returns: This method will always trigger a runtime crash and never return. + /// - Returns: An instance of the specialized type. /// - /// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - /// - Warning: Invoking this method will lead to a fatal error. - @available(*, deprecated, message: "This cast will always fail") + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// + /// - Note: In most cases, this is casting a ``DeclSyntaxProtocol`` to a node that is not a + /// ``DeclSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``DeclSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'DeclSyntaxProtocol' hierarchy") public func cast(_ syntaxType: S.Type) -> S { - fatalError("\(Self.self) cannot be cast to \(S.self)") + return self.as(S.self)! } } @@ -359,6 +358,7 @@ extension ExprSyntaxProtocol { /// Force-casts the current syntax node to a given specialized syntax type. /// /// - Returns: An instance of the specialized type. + /// /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! @@ -368,9 +368,6 @@ extension ExprSyntaxProtocol { /// Checks if the current syntax node can be upcast to its base node type (``ExprSyntax``). /// /// - Returns: `true` since the node can always be upcast to its base node. - /// - /// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning - /// informing the user that the upcast will always succeed. @available(*, deprecated, message: "This cast will always succeed") public func `is`(_ syntaxType: ExprSyntax.Type) -> Bool { return true @@ -380,9 +377,6 @@ extension ExprSyntaxProtocol { /// Attempts to upcast the current syntax node to its base node type (``ExprSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `ExprSyntax.init` for upcasting") public func `as`(_ syntaxType: ExprSyntax.Type) -> ExprSyntax? { return ExprSyntax(self) @@ -392,49 +386,53 @@ extension ExprSyntaxProtocol { /// Force-upcast the current syntax node to its base node type (``ExprSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `ExprSyntax.init` for upcasting") public func cast(_ syntaxType: ExprSyntax.Type) -> ExprSyntax { return ExprSyntax(self) } - /// Checks if the current syntax node can be cast to a given node type from the different base node protocol hierarchy than ``ExprSyntaxProtocol``. + /// Checks if the current syntax node can be cast to a given node type from a base node protocol hierarchy other + /// than ``ExprSyntaxProtocol``. /// - /// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``ExprSyntaxProtocol``. + /// - Returns: `true` if the node can be cast, `false` otherwise. /// - /// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is comparing a ``ExprSyntaxProtocol`` to a node that is not a + /// ``ExprSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``ExprSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'ExprSyntaxProtocol' hierarchy") public func `is`(_ syntaxType: S.Type) -> Bool { - return false + return self.as(syntaxType) != nil } - /// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``ExprSyntaxProtocol``. + /// Attempts to cast the current syntax node to a given node type from the a base node protocol hierarchy other than + /// ``ExprSyntaxProtocol``. /// - /// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``ExprSyntaxProtocol``. + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. /// - /// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``ExprSyntaxProtocol`` to a node that is not a + /// ``ExprSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``ExprSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'ExprSyntaxProtocol' hierarchy") public func `as`(_ syntaxType: S.Type) -> S? { - return nil + return S.init(self) } - /// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``ExprSyntaxProtocol``. + /// Force-casts the current syntax node to a given node type from a base node protocol hierarchy other than + /// ``ExprSyntaxProtocol``. /// - /// - Returns: This method will always trigger a runtime crash and never return. + /// - Returns: An instance of the specialized type. /// - /// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - /// - Warning: Invoking this method will lead to a fatal error. - @available(*, deprecated, message: "This cast will always fail") + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// + /// - Note: In most cases, this is casting a ``ExprSyntaxProtocol`` to a node that is not a + /// ``ExprSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``ExprSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'ExprSyntaxProtocol' hierarchy") public func cast(_ syntaxType: S.Type) -> S { - fatalError("\(Self.self) cannot be cast to \(S.self)") + return self.as(S.self)! } } @@ -718,6 +716,7 @@ extension PatternSyntaxProtocol { /// Force-casts the current syntax node to a given specialized syntax type. /// /// - Returns: An instance of the specialized type. + /// /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! @@ -727,9 +726,6 @@ extension PatternSyntaxProtocol { /// Checks if the current syntax node can be upcast to its base node type (``PatternSyntax``). /// /// - Returns: `true` since the node can always be upcast to its base node. - /// - /// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning - /// informing the user that the upcast will always succeed. @available(*, deprecated, message: "This cast will always succeed") public func `is`(_ syntaxType: PatternSyntax.Type) -> Bool { return true @@ -739,9 +735,6 @@ extension PatternSyntaxProtocol { /// Attempts to upcast the current syntax node to its base node type (``PatternSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `PatternSyntax.init` for upcasting") public func `as`(_ syntaxType: PatternSyntax.Type) -> PatternSyntax? { return PatternSyntax(self) @@ -751,49 +744,53 @@ extension PatternSyntaxProtocol { /// Force-upcast the current syntax node to its base node type (``PatternSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `PatternSyntax.init` for upcasting") public func cast(_ syntaxType: PatternSyntax.Type) -> PatternSyntax { return PatternSyntax(self) } - /// Checks if the current syntax node can be cast to a given node type from the different base node protocol hierarchy than ``PatternSyntaxProtocol``. + /// Checks if the current syntax node can be cast to a given node type from a base node protocol hierarchy other + /// than ``PatternSyntaxProtocol``. /// - /// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``PatternSyntaxProtocol``. + /// - Returns: `true` if the node can be cast, `false` otherwise. /// - /// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is comparing a ``PatternSyntaxProtocol`` to a node that is not a + /// ``PatternSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``PatternSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'PatternSyntaxProtocol' hierarchy") public func `is`(_ syntaxType: S.Type) -> Bool { - return false + return self.as(syntaxType) != nil } - /// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``PatternSyntaxProtocol``. + /// Attempts to cast the current syntax node to a given node type from the a base node protocol hierarchy other than + /// ``PatternSyntaxProtocol``. /// - /// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``PatternSyntaxProtocol``. + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. /// - /// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``PatternSyntaxProtocol`` to a node that is not a + /// ``PatternSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``PatternSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'PatternSyntaxProtocol' hierarchy") public func `as`(_ syntaxType: S.Type) -> S? { - return nil + return S.init(self) } - /// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``PatternSyntaxProtocol``. + /// Force-casts the current syntax node to a given node type from a base node protocol hierarchy other than + /// ``PatternSyntaxProtocol``. /// - /// - Returns: This method will always trigger a runtime crash and never return. + /// - Returns: An instance of the specialized type. /// - /// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - /// - Warning: Invoking this method will lead to a fatal error. - @available(*, deprecated, message: "This cast will always fail") + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// + /// - Note: In most cases, this is casting a ``PatternSyntaxProtocol`` to a node that is not a + /// ``PatternSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``PatternSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'PatternSyntaxProtocol' hierarchy") public func cast(_ syntaxType: S.Type) -> S { - fatalError("\(Self.self) cannot be cast to \(S.self)") + return self.as(S.self)! } } @@ -986,6 +983,7 @@ extension StmtSyntaxProtocol { /// Force-casts the current syntax node to a given specialized syntax type. /// /// - Returns: An instance of the specialized type. + /// /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! @@ -995,9 +993,6 @@ extension StmtSyntaxProtocol { /// Checks if the current syntax node can be upcast to its base node type (``StmtSyntax``). /// /// - Returns: `true` since the node can always be upcast to its base node. - /// - /// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning - /// informing the user that the upcast will always succeed. @available(*, deprecated, message: "This cast will always succeed") public func `is`(_ syntaxType: StmtSyntax.Type) -> Bool { return true @@ -1007,9 +1002,6 @@ extension StmtSyntaxProtocol { /// Attempts to upcast the current syntax node to its base node type (``StmtSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `StmtSyntax.init` for upcasting") public func `as`(_ syntaxType: StmtSyntax.Type) -> StmtSyntax? { return StmtSyntax(self) @@ -1019,49 +1011,53 @@ extension StmtSyntaxProtocol { /// Force-upcast the current syntax node to its base node type (``StmtSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `StmtSyntax.init` for upcasting") public func cast(_ syntaxType: StmtSyntax.Type) -> StmtSyntax { return StmtSyntax(self) } - /// Checks if the current syntax node can be cast to a given node type from the different base node protocol hierarchy than ``StmtSyntaxProtocol``. + /// Checks if the current syntax node can be cast to a given node type from a base node protocol hierarchy other + /// than ``StmtSyntaxProtocol``. /// - /// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``StmtSyntaxProtocol``. + /// - Returns: `true` if the node can be cast, `false` otherwise. /// - /// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is comparing a ``StmtSyntaxProtocol`` to a node that is not a + /// ``StmtSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``StmtSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'StmtSyntaxProtocol' hierarchy") public func `is`(_ syntaxType: S.Type) -> Bool { - return false + return self.as(syntaxType) != nil } - /// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``StmtSyntaxProtocol``. + /// Attempts to cast the current syntax node to a given node type from the a base node protocol hierarchy other than + /// ``StmtSyntaxProtocol``. /// - /// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``StmtSyntaxProtocol``. + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. /// - /// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``StmtSyntaxProtocol`` to a node that is not a + /// ``StmtSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``StmtSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'StmtSyntaxProtocol' hierarchy") public func `as`(_ syntaxType: S.Type) -> S? { - return nil + return S.init(self) } - /// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``StmtSyntaxProtocol``. + /// Force-casts the current syntax node to a given node type from a base node protocol hierarchy other than + /// ``StmtSyntaxProtocol``. /// - /// - Returns: This method will always trigger a runtime crash and never return. + /// - Returns: An instance of the specialized type. /// - /// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - /// - Warning: Invoking this method will lead to a fatal error. - @available(*, deprecated, message: "This cast will always fail") + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// + /// - Note: In most cases, this is casting a ``StmtSyntaxProtocol`` to a node that is not a + /// ``StmtSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``StmtSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'StmtSyntaxProtocol' hierarchy") public func cast(_ syntaxType: S.Type) -> S { - fatalError("\(Self.self) cannot be cast to \(S.self)") + return self.as(S.self)! } } @@ -1273,6 +1269,7 @@ extension TypeSyntaxProtocol { /// Force-casts the current syntax node to a given specialized syntax type. /// /// - Returns: An instance of the specialized type. + /// /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! @@ -1282,9 +1279,6 @@ extension TypeSyntaxProtocol { /// Checks if the current syntax node can be upcast to its base node type (``TypeSyntax``). /// /// - Returns: `true` since the node can always be upcast to its base node. - /// - /// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning - /// informing the user that the upcast will always succeed. @available(*, deprecated, message: "This cast will always succeed") public func `is`(_ syntaxType: TypeSyntax.Type) -> Bool { return true @@ -1294,9 +1288,6 @@ extension TypeSyntaxProtocol { /// Attempts to upcast the current syntax node to its base node type (``TypeSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `TypeSyntax.init` for upcasting") public func `as`(_ syntaxType: TypeSyntax.Type) -> TypeSyntax? { return TypeSyntax(self) @@ -1306,49 +1297,53 @@ extension TypeSyntaxProtocol { /// Force-upcast the current syntax node to its base node type (``TypeSyntax``). /// /// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type. - /// - /// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning - /// informing the user the upcast should be performed using the target base node's initializer. @available(*, deprecated, message: "Use `TypeSyntax.init` for upcasting") public func cast(_ syntaxType: TypeSyntax.Type) -> TypeSyntax { return TypeSyntax(self) } - /// Checks if the current syntax node can be cast to a given node type from the different base node protocol hierarchy than ``TypeSyntaxProtocol``. + /// Checks if the current syntax node can be cast to a given node type from a base node protocol hierarchy other + /// than ``TypeSyntaxProtocol``. /// - /// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``TypeSyntaxProtocol``. + /// - Returns: `true` if the node can be cast, `false` otherwise. /// - /// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is comparing a ``TypeSyntaxProtocol`` to a node that is not a + /// ``TypeSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``TypeSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'TypeSyntaxProtocol' hierarchy") public func `is`(_ syntaxType: S.Type) -> Bool { - return false + return self.as(syntaxType) != nil } - /// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``TypeSyntaxProtocol``. + /// Attempts to cast the current syntax node to a given node type from the a base node protocol hierarchy other than + /// ``TypeSyntaxProtocol``. /// - /// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``TypeSyntaxProtocol``. + /// - Returns: An instance of the specialized type, or `nil` if the cast fails. /// - /// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - @available(*, deprecated, message: "This cast will always fail") + /// - Note: In most cases, this is casting a ``TypeSyntaxProtocol`` to a node that is not a + /// ``TypeSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``TypeSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'TypeSyntaxProtocol' hierarchy") public func `as`(_ syntaxType: S.Type) -> S? { - return nil + return S.init(self) } - /// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``TypeSyntaxProtocol``. + /// Force-casts the current syntax node to a given node type from a base node protocol hierarchy other than + /// ``TypeSyntaxProtocol``. /// - /// - Returns: This method will always trigger a runtime crash and never return. + /// - Returns: An instance of the specialized type. /// - /// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning, - /// informing the user that the cast will always fail. - /// - Warning: Invoking this method will lead to a fatal error. - @available(*, deprecated, message: "This cast will always fail") + /// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast. + /// + /// - Note: In most cases, this is casting a ``TypeSyntaxProtocol`` to a node that is not a + /// ``TypeSyntaxProtocol``, which will always fail. If the `syntaxType` argument is a generic type, + /// constrain it to ``TypeSyntaxProtocol`` instead of ``SyntaxProtocol``. + @available(*, deprecated, message: "Type argument should be part of the 'TypeSyntaxProtocol' hierarchy") public func cast(_ syntaxType: S.Type) -> S { - fatalError("\(Self.self) cannot be cast to \(S.self)") + return self.as(S.self)! } }