@@ -14,29 +14,29 @@ import SwiftSyntax
14
14
15
15
@_spi ( Experimental) public enum LookupName {
16
16
/// Identifier associated with the name.
17
- /// Could be an identifier of a variable, function or closure parameter and more
17
+ /// Could be an identifier of a variable, function or closure parameter and more.
18
18
case identifier( IdentifiableSyntax , accessibleAfter: AbsolutePosition ? )
19
19
/// Declaration associated with the name.
20
- /// Could be class, struct, actor, protocol, function and more
20
+ /// Could be class, struct, actor, protocol, function and more.
21
21
case declaration( NamedDeclSyntax , accessibleAfter: AbsolutePosition ? )
22
22
23
23
/// Syntax associated with this name.
24
24
@_spi ( Experimental) public var syntax : SyntaxProtocol {
25
25
switch self {
26
26
case . identifier( let syntax, _) :
27
- syntax
27
+ return syntax
28
28
case . declaration( let syntax, _) :
29
- syntax
29
+ return syntax
30
30
}
31
31
}
32
32
33
33
/// Introduced name.
34
34
@_spi ( Experimental) public var identifier : Identifier ? {
35
35
switch self {
36
36
case . identifier( let syntax, _) :
37
- Identifier ( syntax. identifier)
37
+ return Identifier ( syntax. identifier)
38
38
case . declaration( let syntax, _) :
39
- Identifier ( syntax. name)
39
+ return Identifier ( syntax. name)
40
40
}
41
41
}
42
42
@@ -45,7 +45,7 @@ import SwiftSyntax
45
45
var accessibleAfter : AbsolutePosition ? {
46
46
switch self {
47
47
case . identifier( _, let absolutePosition) , . declaration( _, let absolutePosition) :
48
- absolutePosition
48
+ return absolutePosition
49
49
}
50
50
}
51
51
@@ -61,62 +61,78 @@ import SwiftSyntax
61
61
return name == lookedUpName
62
62
}
63
63
64
- /// Extracts names introduced by the given `from` structure.
65
- static func getNames( from syntax: SyntaxProtocol , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ] {
64
+ /// Extracts names introduced by the given `syntax` structure.
65
+ ///
66
+ /// When e.g. looking up a variable declaration like `let a = a`,
67
+ /// we expect `a` to be visible after the whole declaration.
68
+ /// That's why we can't just use `syntax.endPosition` for the `a` identifier pattern,
69
+ /// as the name would already be visible at the `a` reference withing the declaration.
70
+ /// That’s why code block and file scopes have to set
71
+ /// `accessibleAfter` to be the end position of the entire declaration syntax node.
72
+ static func getNames(
73
+ from syntax: SyntaxProtocol ,
74
+ accessibleAfter: AbsolutePosition ? = nil
75
+ ) -> [ LookupName ] {
66
76
switch Syntax ( syntax) . as ( SyntaxEnum . self) {
67
77
case . variableDecl( let variableDecl) :
68
- variableDecl. bindings. flatMap { binding in
69
- getNames ( from: binding. pattern, accessibleAfter: accessibleAfter)
78
+ return variableDecl. bindings. flatMap { binding in
79
+ getNames (
80
+ from: binding. pattern,
81
+ accessibleAfter: accessibleAfter != nil ? binding. endPositionBeforeTrailingTrivia : nil
82
+ )
70
83
}
71
84
case . tuplePattern( let tuplePattern) :
72
- tuplePattern. elements. flatMap { tupleElement in
85
+ return tuplePattern. elements. flatMap { tupleElement in
73
86
getNames ( from: tupleElement. pattern, accessibleAfter: accessibleAfter)
74
87
}
75
88
case . valueBindingPattern( let valueBindingPattern) :
76
- getNames ( from: valueBindingPattern. pattern, accessibleAfter: accessibleAfter)
89
+ return getNames ( from: valueBindingPattern. pattern, accessibleAfter: accessibleAfter)
77
90
case . expressionPattern( let expressionPattern) :
78
- getNames ( from: expressionPattern. expression, accessibleAfter: accessibleAfter)
91
+ return getNames ( from: expressionPattern. expression, accessibleAfter: accessibleAfter)
79
92
case . sequenceExpr( let sequenceExpr) :
80
- sequenceExpr. elements. flatMap { expression in
93
+ return sequenceExpr. elements. flatMap { expression in
81
94
getNames ( from: expression, accessibleAfter: accessibleAfter)
82
95
}
83
96
case . patternExpr( let patternExpr) :
84
- getNames ( from: patternExpr. pattern, accessibleAfter: accessibleAfter)
97
+ return getNames ( from: patternExpr. pattern, accessibleAfter: accessibleAfter)
85
98
case . optionalBindingCondition( let optionalBinding) :
86
- getNames ( from: optionalBinding. pattern, accessibleAfter: accessibleAfter)
99
+ return getNames ( from: optionalBinding. pattern, accessibleAfter: accessibleAfter)
87
100
case . matchingPatternCondition( let matchingPatternCondition) :
88
- getNames ( from: matchingPatternCondition. pattern, accessibleAfter: accessibleAfter)
101
+ return getNames ( from: matchingPatternCondition. pattern, accessibleAfter: accessibleAfter)
89
102
case . functionCallExpr( let functionCallExpr) :
90
- functionCallExpr. arguments. flatMap { argument in
103
+ return functionCallExpr. arguments. flatMap { argument in
91
104
getNames ( from: argument. expression, accessibleAfter: accessibleAfter)
92
105
}
93
106
case . guardStmt( let guardStmt) :
94
- guardStmt. conditions. flatMap { cond in
107
+ return guardStmt. conditions. flatMap { cond in
95
108
getNames ( from: cond. condition, accessibleAfter: cond. endPosition)
96
109
}
97
110
default :
98
111
if let namedDecl = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? NamedDeclSyntax {
99
- handle ( namedDecl: namedDecl, accessibleAfter: accessibleAfter)
112
+ return handle ( namedDecl: namedDecl, accessibleAfter: accessibleAfter)
100
113
} else if let identifiable = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? IdentifiableSyntax {
101
- handle ( identifiable: identifiable, accessibleAfter: accessibleAfter)
114
+ return handle ( identifiable: identifiable, accessibleAfter: accessibleAfter)
102
115
} else {
103
- [ ]
116
+ return [ ]
104
117
}
105
118
}
106
119
}
107
120
108
121
/// Extracts name introduced by `IdentifiableSyntax` node.
109
122
private static func handle( identifiable: IdentifiableSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ]
110
123
{
111
- if identifiable. identifier. text != " _ " {
124
+ if identifiable. identifier. tokenKind != . wildcard {
112
125
return [ . identifier( identifiable, accessibleAfter: accessibleAfter) ]
113
126
} else {
114
127
return [ ]
115
128
}
116
129
}
117
130
118
131
/// Extracts name introduced by `NamedDeclSyntax` node.
119
- private static func handle( namedDecl: NamedDeclSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ] {
132
+ private static func handle(
133
+ namedDecl: NamedDeclSyntax ,
134
+ accessibleAfter: AbsolutePosition ? = nil
135
+ ) -> [ LookupName ] {
120
136
[ . declaration( namedDecl, accessibleAfter: accessibleAfter) ]
121
137
}
122
138
}
0 commit comments