You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -31,6 +31,117 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
31
31
"""
32
32
)
33
33
34
+
DeclSyntax(
35
+
#"""
36
+
/// Extension of ``\#(node.kind.protocolType)`` to provide casting methods.
37
+
///
38
+
/// These methods enable casting between syntax node types within the same
39
+
/// base node protocol hierarchy (e.g., ``DeclSyntaxProtocol``).
40
+
///
41
+
/// While ``SyntaxProtocol`` offers general casting methods (``SyntaxProtocol.as(_:)``,
42
+
/// ``SyntaxProtocol.is(_:)``, and ``SyntaxProtocol.cast(_:)``), these often aren't
43
+
/// appropriate for use on types conforming to a specific base node protocol
44
+
/// like ``\#(node.kind.protocolType)``. That's because at this level,
45
+
/// we know that the cast to another base node type (e.g., ``DeclSyntaxProtocol``
46
+
/// when working with ``ExprSyntaxProtocol``) is guaranteed to fail.
47
+
///
48
+
/// To guide developers toward correct usage, this extension provides overloads
49
+
/// of these casting methods that are restricted to the same base node type.
50
+
/// Furthermore, it marks the inherited casting methods from ``SyntaxProtocol`` as
51
+
/// deprecated, indicating that they will always fail when used in this context.
52
+
extension \#(node.kind.protocolType){
53
+
/// Checks if the current syntax node can be cast to a given specialized syntax type.
54
+
///
55
+
/// - Returns: `true` if the node can be cast, `false` otherwise.
56
+
public func `is`<S: \#(node.kind.protocolType)>(_ syntaxType: S.Type) -> Bool {
57
+
return self.as(syntaxType) != nil
58
+
}
59
+
60
+
/// Attempts to cast the current syntax node to a given specialized syntax type.
61
+
///
62
+
/// - Returns: An instance of the specialized type, or `nil` if the cast fails.
63
+
public func `as`<S: \#(node.kind.protocolType)>(_ syntaxType: S.Type) -> S? {
64
+
return S.init(self)
65
+
}
66
+
67
+
/// Force-casts the current syntax node to a given specialized syntax type.
68
+
///
69
+
/// - Returns: An instance of the specialized type.
70
+
/// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast.
71
+
public func cast<S: \#(node.kind.protocolType)>(_ syntaxType: S.Type) -> S {
72
+
return self.as(S.self)!
73
+
}
74
+
75
+
/// Checks if the current syntax node can be upcast to its base node type (``\#(node.kind.syntaxType)``).
76
+
///
77
+
/// - Returns: `true` since the node can always be upcast to its base node.
78
+
///
79
+
/// - Note: This method overloads the general `is` method and is marked deprecated to produce a warning
80
+
/// informing the user that the upcast will always succeed.
81
+
@available(*, deprecated, message: "This cast will always succeed")
82
+
public func `is`(_ syntaxType: \#(node.kind.syntaxType).Type) -> Bool {
83
+
return true
84
+
}
85
+
86
+
/// Attempts to upcast the current syntax node to its base node type (``\#(node.kind.syntaxType)``).
87
+
///
88
+
/// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type.
89
+
///
90
+
/// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning
91
+
/// informing the user the upcast should be performed using the target base node's initializer.
92
+
@available(*, deprecated, message: "Use `\#(node.kind.syntaxType).init` for upcasting")
93
+
public func `as`(_ syntaxType: \#(node.kind.syntaxType).Type) -> \#(node.kind.syntaxType)? {
94
+
return \#(node.kind.syntaxType)(self)
95
+
}
96
+
97
+
/// Force-upcast the current syntax node to its base node type (``\#(node.kind.syntaxType)``).
98
+
///
99
+
/// - Returns: The base node created from the current syntax node, as the node can always be upcast to its base type.
100
+
///
101
+
/// - Note: This method overloads the general `as` method and is marked deprecated to produce a warning
102
+
/// informing the user the upcast should be performed using the target base node's initializer.
103
+
@available(*, deprecated, message: "Use `\#(node.kind.syntaxType).init` for upcasting")
104
+
public func cast(_ syntaxType: \#(node.kind.syntaxType).Type) -> \#(node.kind.syntaxType){
105
+
return \#(node.kind.syntaxType)(self)
106
+
}
107
+
108
+
/// 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)``.
109
+
///
110
+
/// - Returns: `false` since the node can not be cast to the node type from different base node protocol hierarchy than ``\#(node.kind.protocolType)``.
111
+
///
112
+
/// - Note: This method overloads the general `is` method and is marked as deprecated to produce a warning,
113
+
/// informing the user that the cast will always fail.
114
+
@available(*, deprecated, message: "This cast will always fail")
115
+
public func `is`<S: SyntaxProtocol>(_ syntaxType: S.Type) -> Bool {
116
+
return false
117
+
}
118
+
119
+
/// Attempts to cast the current syntax node to a given node type from the different base node protocol hierarchy than ``\#(node.kind.protocolType)``.
120
+
///
121
+
/// - Returns: `nil` since the node can not be cast to the node type from different base node protocol hierarchy than ``\#(node.kind.protocolType)``.
122
+
///
123
+
/// - Note: This method overloads the general `as` method and is marked as deprecated to produce a warning,
124
+
/// informing the user that the cast will always fail.
125
+
@available(*, deprecated, message: "This cast will always fail")
126
+
public func `as`<S: SyntaxProtocol>(_ syntaxType: S.Type) -> S? {
127
+
return nil
128
+
}
129
+
130
+
/// Force-casts the current syntax node to a given node type from the different base node protocol hierarchy than ``\#(node.kind.protocolType)``.
131
+
///
132
+
/// - Returns: This method will always trigger a runtime crash and never return.
133
+
///
134
+
/// - Note: This method overloads the general `cast` method and is marked as deprecated to produce a warning,
135
+
/// informing the user that the cast will always fail.
136
+
/// - Warning: Invoking this method will lead to a fatal error.
137
+
@available(*, deprecated, message: "This cast will always fail")
138
+
public func cast<S: SyntaxProtocol>(_ syntaxType: S.Type) -> S {
139
+
fatalError("\(Self.self) cannot be cast to \(S.self)")
Copy file name to clipboardExpand all lines: Release Notes/510.md
+15Lines changed: 15 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,21 @@
25
25
26
26
## Deprecations
27
27
28
+
- Leaf Node Casts
29
+
- Description: Syntax nodes that do not act as base nodes for other syntax types have the casting methods marked as deprecated. This prevents unsafe type-casting by issuing deprecation warnings for methods that will always result in failed casts.
- Description: `is`, `as`, and `cast` overloads on `SyntaxProtocol` with same-type conversions are marked as deprecated. The deprecated methods emit a warning indicating the cast will always succeed.
- Description: `is`, `as`, and `cast` methods on base node protocols with base-type conversions are marked as deprecated. The deprecated methods emit a warning that informs the developer that the cast will always succeed and should be done using the base node's initializer.
0 commit comments