12
12
13
13
import SwiftSyntax
14
14
15
+ @_spi ( Experimental) public enum LookupImplicitNameKind {
16
+ /// `self` keyword representing object instance.
17
+ case `self`( SyntaxProtocol )
18
+ /// `Self` keyword representing object type.
19
+ case `Self`( DeclSyntaxProtocol )
20
+ /// `self` captured by a closure.
21
+ case error( CatchClauseSyntax )
22
+ /// `newValue` available by default inside `set` and `willSet`.
23
+ case newValue( AccessorDeclSyntax )
24
+ /// `oldValue` available by default inside `didSet`.
25
+ case oldValue( AccessorDeclSyntax )
26
+
27
+ /// Syntax associated with this name.
28
+ @_spi ( Experimental) public var syntax : SyntaxProtocol {
29
+ switch self {
30
+ case . self ( let syntax) :
31
+ syntax
32
+ case . Self( let syntax) :
33
+ syntax
34
+ case . error( let syntax) :
35
+ syntax
36
+ case . newValue( let syntax) :
37
+ syntax
38
+ case . oldValue( let syntax) :
39
+ syntax
40
+ }
41
+ }
42
+
43
+ /// Used for name comparison.
44
+ var name : String {
45
+ switch self {
46
+ case . self :
47
+ " self "
48
+ case . Self:
49
+ " Self "
50
+ case . error:
51
+ " error "
52
+ case . newValue:
53
+ " newValue "
54
+ case . oldValue:
55
+ " oldValue "
56
+ }
57
+ }
58
+ }
59
+
15
60
@_spi ( Experimental) public enum LookupName {
16
61
/// Identifier associated with the name.
17
- /// Could be an identifier of a variable, function or closure parameter and more
62
+ /// Could be an identifier of a variable, function or closure parameter and more.
18
63
case identifier( IdentifiableSyntax , accessibleAfter: AbsolutePosition ? )
19
64
/// Declaration associated with the name.
20
- /// Could be class, struct, actor, protocol, function and more
65
+ /// Could be class, struct, actor, protocol, function and more.
21
66
case declaration( NamedDeclSyntax , accessibleAfter: AbsolutePosition ? )
67
+ /// Name introduced implicitly certain syntax nodes.
68
+ case implicit( LookupImplicitNameKind )
22
69
23
70
/// Syntax associated with this name.
24
71
@_spi ( Experimental) public var syntax : SyntaxProtocol {
@@ -27,6 +74,8 @@ import SwiftSyntax
27
74
syntax
28
75
case . declaration( let syntax, _) :
29
76
syntax
77
+ case . implicit( let implicitName) :
78
+ implicitName. syntax
30
79
}
31
80
}
32
81
@@ -37,6 +86,8 @@ import SwiftSyntax
37
86
Identifier ( syntax. identifier)
38
87
case . declaration( let syntax, _) :
39
88
Identifier ( syntax. name)
89
+ default :
90
+ nil
40
91
}
41
92
}
42
93
@@ -46,6 +97,18 @@ import SwiftSyntax
46
97
switch self {
47
98
case . identifier( _, let absolutePosition) , . declaration( _, let absolutePosition) :
48
99
absolutePosition
100
+ default :
101
+ nil
102
+ }
103
+ }
104
+
105
+ /// Used for name comparison.
106
+ var name : String ? {
107
+ switch self {
108
+ case . identifier, . declaration:
109
+ identifier? . name
110
+ case . implicit( let implicitName) :
111
+ implicitName. name
49
112
}
50
113
}
51
114
@@ -57,12 +120,15 @@ import SwiftSyntax
57
120
58
121
/// Checks if this name refers to the looked up phrase.
59
122
func refersTo( _ lookedUpName: String ) -> Bool {
60
- guard let name = identifier ? . name else { return false }
123
+ guard let name else { return false }
61
124
return name == lookedUpName
62
125
}
63
126
64
- /// Extracts names introduced by the given `from` structure.
65
- static func getNames( from syntax: SyntaxProtocol , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ] {
127
+ /// Extracts names introduced by the given `syntax` structure.
128
+ static func getNames(
129
+ from syntax: SyntaxProtocol ,
130
+ accessibleAfter: AbsolutePosition ? = nil
131
+ ) -> [ LookupName ] {
66
132
switch Syntax ( syntax) . as ( SyntaxEnum . self) {
67
133
case . variableDecl( let variableDecl) :
68
134
variableDecl. bindings. flatMap { binding in
@@ -90,10 +156,6 @@ import SwiftSyntax
90
156
functionCallExpr. arguments. flatMap { argument in
91
157
getNames ( from: argument. expression, accessibleAfter: accessibleAfter)
92
158
}
93
- case . guardStmt( let guardStmt) :
94
- guardStmt. conditions. flatMap { cond in
95
- getNames ( from: cond. condition, accessibleAfter: cond. endPosition)
96
- }
97
159
default :
98
160
if let namedDecl = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? NamedDeclSyntax {
99
161
handle ( namedDecl: namedDecl, accessibleAfter: accessibleAfter)
@@ -106,17 +168,26 @@ import SwiftSyntax
106
168
}
107
169
108
170
/// Extracts name introduced by `IdentifiableSyntax` node.
109
- private static func handle( identifiable: IdentifiableSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ]
110
- {
111
- if identifiable. identifier. text != " _ " {
171
+ private static func handle(
172
+ identifiable: IdentifiableSyntax ,
173
+ accessibleAfter: AbsolutePosition ? = nil
174
+ ) -> [ LookupName ] {
175
+ if let closureCapture = identifiable as? ClosureCaptureSyntax ,
176
+ closureCapture. identifier. tokenKind == . keyword( . self )
177
+ {
178
+ return [ . implicit( . self ( closureCapture) ) ] // Handle `self` closure capture.
179
+ } else if identifiable. identifier. tokenKind != . wildcard {
112
180
return [ . identifier( identifiable, accessibleAfter: accessibleAfter) ]
113
181
} else {
114
182
return [ ]
115
183
}
116
184
}
117
185
118
186
/// Extracts name introduced by `NamedDeclSyntax` node.
119
- private static func handle( namedDecl: NamedDeclSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ] {
187
+ private static func handle(
188
+ namedDecl: NamedDeclSyntax ,
189
+ accessibleAfter: AbsolutePosition ? = nil
190
+ ) -> [ LookupName ] {
120
191
[ . declaration( namedDecl, accessibleAfter: accessibleAfter) ]
121
192
}
122
193
}
0 commit comments