@@ -14,29 +14,29 @@ import SwiftSyntax
1414
1515@_spi ( Experimental) public enum LookupName {
1616 /// 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.
1818 case identifier( IdentifiableSyntax , accessibleAfter: AbsolutePosition ? )
1919 /// 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.
2121 case declaration( NamedDeclSyntax , accessibleAfter: AbsolutePosition ? )
2222
2323 /// Syntax associated with this name.
2424 @_spi ( Experimental) public var syntax : SyntaxProtocol {
2525 switch self {
2626 case . identifier( let syntax, _) :
27- syntax
27+ return syntax
2828 case . declaration( let syntax, _) :
29- syntax
29+ return syntax
3030 }
3131 }
3232
3333 /// Introduced name.
3434 @_spi ( Experimental) public var identifier : Identifier ? {
3535 switch self {
3636 case . identifier( let syntax, _) :
37- Identifier ( syntax. identifier)
37+ return Identifier ( syntax. identifier)
3838 case . declaration( let syntax, _) :
39- Identifier ( syntax. name)
39+ return Identifier ( syntax. name)
4040 }
4141 }
4242
@@ -45,7 +45,7 @@ import SwiftSyntax
4545 var accessibleAfter : AbsolutePosition ? {
4646 switch self {
4747 case . identifier( _, let absolutePosition) , . declaration( _, let absolutePosition) :
48- absolutePosition
48+ return absolutePosition
4949 }
5050 }
5151
@@ -61,62 +61,78 @@ import SwiftSyntax
6161 return name == lookedUpName
6262 }
6363
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 ] {
6676 switch Syntax ( syntax) . as ( SyntaxEnum . self) {
6777 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+ )
7083 }
7184 case . tuplePattern( let tuplePattern) :
72- tuplePattern. elements. flatMap { tupleElement in
85+ return tuplePattern. elements. flatMap { tupleElement in
7386 getNames ( from: tupleElement. pattern, accessibleAfter: accessibleAfter)
7487 }
7588 case . valueBindingPattern( let valueBindingPattern) :
76- getNames ( from: valueBindingPattern. pattern, accessibleAfter: accessibleAfter)
89+ return getNames ( from: valueBindingPattern. pattern, accessibleAfter: accessibleAfter)
7790 case . expressionPattern( let expressionPattern) :
78- getNames ( from: expressionPattern. expression, accessibleAfter: accessibleAfter)
91+ return getNames ( from: expressionPattern. expression, accessibleAfter: accessibleAfter)
7992 case . sequenceExpr( let sequenceExpr) :
80- sequenceExpr. elements. flatMap { expression in
93+ return sequenceExpr. elements. flatMap { expression in
8194 getNames ( from: expression, accessibleAfter: accessibleAfter)
8295 }
8396 case . patternExpr( let patternExpr) :
84- getNames ( from: patternExpr. pattern, accessibleAfter: accessibleAfter)
97+ return getNames ( from: patternExpr. pattern, accessibleAfter: accessibleAfter)
8598 case . optionalBindingCondition( let optionalBinding) :
86- getNames ( from: optionalBinding. pattern, accessibleAfter: accessibleAfter)
99+ return getNames ( from: optionalBinding. pattern, accessibleAfter: accessibleAfter)
87100 case . matchingPatternCondition( let matchingPatternCondition) :
88- getNames ( from: matchingPatternCondition. pattern, accessibleAfter: accessibleAfter)
101+ return getNames ( from: matchingPatternCondition. pattern, accessibleAfter: accessibleAfter)
89102 case . functionCallExpr( let functionCallExpr) :
90- functionCallExpr. arguments. flatMap { argument in
103+ return functionCallExpr. arguments. flatMap { argument in
91104 getNames ( from: argument. expression, accessibleAfter: accessibleAfter)
92105 }
93106 case . guardStmt( let guardStmt) :
94- guardStmt. conditions. flatMap { cond in
107+ return guardStmt. conditions. flatMap { cond in
95108 getNames ( from: cond. condition, accessibleAfter: cond. endPosition)
96109 }
97110 default :
98111 if let namedDecl = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? NamedDeclSyntax {
99- handle ( namedDecl: namedDecl, accessibleAfter: accessibleAfter)
112+ return handle ( namedDecl: namedDecl, accessibleAfter: accessibleAfter)
100113 } else if let identifiable = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? IdentifiableSyntax {
101- handle ( identifiable: identifiable, accessibleAfter: accessibleAfter)
114+ return handle ( identifiable: identifiable, accessibleAfter: accessibleAfter)
102115 } else {
103- [ ]
116+ return [ ]
104117 }
105118 }
106119 }
107120
108121 /// Extracts name introduced by `IdentifiableSyntax` node.
109122 private static func handle( identifiable: IdentifiableSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ]
110123 {
111- if identifiable. identifier. text != " _ " {
124+ if identifiable. identifier. tokenKind != . wildcard {
112125 return [ . identifier( identifiable, accessibleAfter: accessibleAfter) ]
113126 } else {
114127 return [ ]
115128 }
116129 }
117130
118131 /// 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 ] {
120136 [ . declaration( namedDecl, accessibleAfter: accessibleAfter) ]
121137 }
122138}
0 commit comments