@@ -14,40 +14,27 @@ import Foundation
14
14
import SwiftSyntax
15
15
16
16
extension SyntaxProtocol {
17
- /// Scope at the syntax node. Could be inherited from parent or introduced at the node.
18
- var scope : Scope ? {
19
- switch self . syntaxNodeType {
20
- case is SourceFileSyntax . Type :
21
- FileScope ( syntax: self )
22
- default :
23
- parent? . scope
24
- }
17
+ /// Given syntax node position, returns all available labeled statements.
18
+ @_spi ( Compiler) @_spi ( Testing) public func lookupLabeledStmts( ) -> [ LabeledStmtSyntax ] {
19
+ return lookupLabeledStmts ( at: self )
25
20
}
26
- }
27
-
28
- /// Provide common functionality for specialized scope implementatations.
29
- protocol Scope {
30
- /// The parent of this scope.
31
- var parent : Scope ? { get }
32
21
33
- /// Syntax node that introduces this protocol.
34
- var sourceSyntax : SyntaxProtocol { get }
35
- }
22
+ /// Given syntax node position, returns the current switch case and it's fallthrough destination.
23
+ @_spi ( Compiler) @_spi ( Testing) public func lookupFallthroughSourceAndDest( )
24
+ -> ( source: SwitchCaseSyntax ? , destination: SwitchCaseSyntax ? )
25
+ {
26
+ return lookupFallthroughSourceAndDestination ( at: self )
27
+ }
36
28
37
- extension Scope {
38
- /// Recursively walks up syntax tree and finds the closest scope other than this scope.
39
- func getParentScope( forSyntax syntax: SyntaxProtocol ? ) -> Scope ? {
40
- if let lookedUpScope = syntax? . scope, lookedUpScope. sourceSyntax. id == syntax? . id {
41
- return getParentScope ( forSyntax: sourceSyntax. parent)
42
- } else {
43
- return syntax? . scope
44
- }
29
+ /// Given syntax node position, returns the closest ancestor catch node.
30
+ @_spi ( Compiler) @_spi ( Testing) public func lookupCatchNode( ) -> Syntax ? {
31
+ return lookupCatchNodeHelper ( at: Syntax ( self ) , traversedCatchClause: false )
45
32
}
46
33
47
34
// MARK: - lookupLabeledStmts
48
35
49
36
/// Given syntax node position, returns all available labeled statements.
50
- func lookupLabeledStmts( at syntax: SyntaxProtocol ) -> [ LabeledStmtSyntax ] {
37
+ private func lookupLabeledStmts( at syntax: SyntaxProtocol ) -> [ LabeledStmtSyntax ] {
51
38
return walkParentTreeUpToFunctionBoundary (
52
39
at: syntax. parent,
53
40
collect: LabeledStmtSyntax . self
@@ -57,7 +44,9 @@ extension Scope {
57
44
// MARK: - lookupFallthroughSourceAndDest
58
45
59
46
/// Given syntax node position, returns the current switch case and it's fallthrough destination.
60
- func lookupFallthroughSourceAndDestination( at syntax: SyntaxProtocol ) -> ( SwitchCaseSyntax ? , SwitchCaseSyntax ? ) {
47
+ private func lookupFallthroughSourceAndDestination( at syntax: SyntaxProtocol )
48
+ -> ( SwitchCaseSyntax ? , SwitchCaseSyntax ? )
49
+ {
61
50
guard
62
51
let originalSwitchCase = walkParentTreeUpToFunctionBoundary (
63
52
at: Syntax ( syntax) ,
@@ -93,11 +82,6 @@ extension Scope {
93
82
94
83
// MARK: - lookupCatchNode
95
84
96
- /// Given syntax node position, returns the closest ancestor catch node.
97
- func lookupCatchNode( at syntax: Syntax ) -> Syntax ? {
98
- return lookupCatchNodeHelper ( at: syntax, traversedCatchClause: false )
99
- }
100
-
101
85
/// Given syntax node location, finds where an error could be caught. If set to `true`, `traverseCatchClause`lookup will skip the next do statement.
102
86
private func lookupCatchNodeHelper( at syntax: Syntax ? , traversedCatchClause: Bool ) -> Syntax ? {
103
87
guard let syntax else { return nil }
@@ -117,23 +101,30 @@ extension Scope {
117
101
} else {
118
102
return lookupCatchNodeHelper ( at: syntax. parent, traversedCatchClause: traversedCatchClause)
119
103
}
120
- case . functionDecl, . accessorDecl, . initializerDecl:
104
+ case . functionDecl, . accessorDecl, . initializerDecl, . deinitializerDecl , . closureExpr :
121
105
return syntax
106
+ case . exprList( let exprList) :
107
+ if let tryExpr = exprList. first? . as ( TryExprSyntax . self) , tryExpr. questionOrExclamationMark != nil {
108
+ return Syntax ( tryExpr)
109
+ }
110
+ return lookupCatchNodeHelper ( at: syntax. parent, traversedCatchClause: traversedCatchClause)
122
111
default :
123
112
return lookupCatchNodeHelper ( at: syntax. parent, traversedCatchClause: traversedCatchClause)
124
113
}
125
114
}
126
115
116
+ // MARK: - walkParentTree helper methods
117
+
127
118
/// Callect the first syntax node matching the collection type up to a function boundary.
128
- func walkParentTreeUpToFunctionBoundary< T: SyntaxProtocol > (
119
+ private func walkParentTreeUpToFunctionBoundary< T: SyntaxProtocol > (
129
120
at syntax: Syntax ? ,
130
121
collect: T . Type
131
122
) -> T ? {
132
123
walkParentTreeUpToFunctionBoundary ( at: syntax, collect: collect, stopWithFirstMatch: true ) . first
133
124
}
134
125
135
126
/// Callect syntax nodes matching the collection type up to a function boundary.
136
- func walkParentTreeUpToFunctionBoundary< T: SyntaxProtocol > (
127
+ private func walkParentTreeUpToFunctionBoundary< T: SyntaxProtocol > (
137
128
at syntax: Syntax ? ,
138
129
collect: T . Type ,
139
130
stopWithFirstMatch: Bool = false
@@ -154,7 +145,7 @@ extension Scope {
154
145
}
155
146
156
147
/// Callect syntax nodes matching the collection type up until encountering one of the specified syntax nodes.
157
- func walkParentTree< T: SyntaxProtocol > (
148
+ private func walkParentTree< T: SyntaxProtocol > (
158
149
upTo stopAt: [ SyntaxProtocol . Type ] ,
159
150
at syntax: Syntax ? ,
160
151
collect: T . Type ,
0 commit comments