@@ -15,34 +15,46 @@ import SwiftSyntax
1515@_spi ( Experimental) public enum LookupName {
1616 /// Identifier associated with the name.
1717 /// Could be an identifier of a variable, function or closure parameter and more
18- case identifier( String , SyntaxProtocol )
18+ case identifier( IdentifiableSyntax , accessibleAfter : AbsolutePosition ? )
1919 /// Declaration associated with the name.
2020 /// Could be class, struct, actor, protocol, function and more
21- case declaration( String , DeclSyntaxProtocol )
21+ case declaration( NamedDeclSyntax , accessibleAfter : AbsolutePosition ? )
2222
2323 /// Syntax associated with this name.
2424 @_spi ( Experimental) public var syntax : SyntaxProtocol {
2525 switch self {
26- case . identifier( _ , let syntax) :
26+ case . identifier( let syntax, _ ) :
2727 syntax
28- case . declaration( _ , let syntax) :
28+ case . declaration( let syntax, _ ) :
2929 syntax
3030 }
3131 }
3232
3333 /// Introduced name.
3434 @_spi ( Experimental) public var name : String {
3535 switch self {
36- case . identifier( let name, _) :
37- name
38- case . declaration( let name, _) :
39- name
36+ case . identifier( let syntax, _) :
37+ syntax. identifier. text
38+ case . declaration( let syntax, _) :
39+ syntax. name. text
40+ }
41+ }
42+
43+ /// Point, after which the name is available in scope.
44+ /// If set to `nil`, the name is available at any point in scope.
45+ var accessibleAfter : AbsolutePosition ? {
46+ switch self {
47+ case . identifier( _, let absolutePosition) :
48+ absolutePosition
49+ case . declaration( _, let absolutePosition) :
50+ absolutePosition
4051 }
4152 }
4253
4354 /// Checks if this name was introduced before the syntax used for lookup.
44- func isBefore( _ lookedUpSyntax: SyntaxProtocol ) -> Bool {
45- syntax. position < lookedUpSyntax. position
55+ func isAccessible( at lookedUpSyntax: SyntaxProtocol ) -> Bool {
56+ guard let accessibleAfter else { return true }
57+ return accessibleAfter <= lookedUpSyntax. position
4658 }
4759
4860 /// Checks if this name refers to the looked up phrase.
@@ -51,91 +63,50 @@ import SwiftSyntax
5163 }
5264
5365 /// Extracts names introduced by the given `from` structure.
54- static func getNames( from syntax: SyntaxProtocol ) -> [ LookupName ] {
66+ static func getNames( from syntax: SyntaxProtocol , accessibleAfter : AbsolutePosition ? = nil ) -> [ LookupName ] {
5567 switch Syntax ( syntax) . as ( SyntaxEnum . self) {
5668 case . variableDecl( let variableDecl) :
5769 variableDecl. bindings. flatMap { binding in
58- getNames ( from: binding. pattern)
70+ getNames ( from: binding. pattern, accessibleAfter : accessibleAfter )
5971 }
6072 case . tuplePattern( let tuplePattern) :
6173 tuplePattern. elements. flatMap { tupleElement in
62- getNames ( from: tupleElement. pattern)
74+ getNames ( from: tupleElement. pattern, accessibleAfter : accessibleAfter )
6375 }
6476 case . valueBindingPattern( let valueBindingPattern) :
65- getNames ( from: valueBindingPattern. pattern)
77+ getNames ( from: valueBindingPattern. pattern, accessibleAfter : accessibleAfter )
6678 case . expressionPattern( let expressionPattern) :
67- getNames ( from: expressionPattern. expression)
79+ getNames ( from: expressionPattern. expression, accessibleAfter : accessibleAfter )
6880 case . sequenceExpr( let sequenceExpr) :
6981 sequenceExpr. elements. flatMap { expression in
70- getNames ( from: expression)
82+ getNames ( from: expression, accessibleAfter : accessibleAfter )
7183 }
7284 case . patternExpr( let patternExpr) :
73- getNames ( from: patternExpr. pattern)
85+ getNames ( from: patternExpr. pattern, accessibleAfter : accessibleAfter )
7486 case . optionalBindingCondition( let optionalBinding) :
75- getNames ( from: optionalBinding. pattern)
76- case . identifierPattern( let identifierPattern) :
77- handle ( identifierPattern: identifierPattern)
78- case . closureShorthandParameter( let closureShorthandParameter) :
79- handle ( closureShorthandParameter: closureShorthandParameter)
80- case . closureParameter( let closureParameter) :
81- handle ( closureParameter: closureParameter)
82- case . functionDecl( let functionDecl) :
83- handle ( functionDecl: functionDecl)
84- case . classDecl( let classDecl) :
85- handle ( classDecl: classDecl)
86- case . structDecl( let structDecl) :
87- handle ( structDecl: structDecl)
88- case . actorDecl( let actorDecl) :
89- handle ( actorDecl: actorDecl)
90- case . protocolDecl( let protocolDecl) :
91- handle ( protocolDecl: protocolDecl)
87+ getNames ( from: optionalBinding. pattern, accessibleAfter: accessibleAfter)
9288 default :
93- [ ]
89+ if let namedDecl = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? NamedDeclSyntax {
90+ handle ( namedDecl: namedDecl, accessibleAfter: accessibleAfter)
91+ } else if let identifiable = Syntax ( syntax) . asProtocol ( SyntaxProtocol . self) as? IdentifiableSyntax {
92+ handle ( identifiable: identifiable, accessibleAfter: accessibleAfter)
93+ } else {
94+ [ ]
95+ }
9496 }
9597 }
9698
97- /// Extracts name introduced by `identifierPattern`.
98- private static func handle( identifierPattern: IdentifierPatternSyntax ) -> [ LookupName ] {
99- [ . identifier( identifierPattern. identifier. text, identifierPattern) ]
100- }
101-
102- /// Extracts name introduced by `closureParameter`.
103- private static func handle( closureParameter: ClosureParameterSyntax ) -> [ LookupName ] {
104- [ . identifier( closureParameter. secondName? . text ?? closureParameter. firstName. text, closureParameter) ]
105- }
106-
107- /// Extracts name introduced by `closureShorthandParameter`.
108- private static func handle( closureShorthandParameter: ClosureShorthandParameterSyntax ) -> [ LookupName ] {
109- let name = closureShorthandParameter. name. text
110- if name != " _ " {
111- return [ . identifier( name, closureShorthandParameter) ]
99+ /// Extracts name introduced by `IdentifiableSyntax` node.
100+ private static func handle( identifiable: IdentifiableSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ] {
101+ if identifiable. identifier. text != " _ " {
102+ return [ . identifier( identifiable, accessibleAfter: accessibleAfter) ]
112103 } else {
113104 return [ ]
114105 }
115106 }
116-
117- /// Extracts name introduced by `functionDecl`.
118- private static func handle( functionDecl: FunctionDeclSyntax ) -> [ LookupName ] {
119- [ . declaration( functionDecl. name. text, functionDecl) ]
120- }
121-
122- /// Extracts name introduced by `classDecl`.
123- private static func handle( classDecl: ClassDeclSyntax ) -> [ LookupName ] {
124- [ . declaration( classDecl. name. text, classDecl) ]
125- }
126-
127- /// Extracts name introduced by `structDecl`.
128- private static func handle( structDecl: StructDeclSyntax ) -> [ LookupName ] {
129- [ . declaration( structDecl. name. text, structDecl) ]
130- }
131-
132- /// Extracts name introduced by `actorDecl`.
133- private static func handle( actorDecl: ActorDeclSyntax ) -> [ LookupName ] {
134- [ . declaration( actorDecl. name. text, actorDecl) ]
135- }
136-
137- /// Extracts name introduced by `protocolDecl`.
138- private static func handle( protocolDecl: ProtocolDeclSyntax ) -> [ LookupName ] {
139- [ . declaration( protocolDecl. name. text, protocolDecl) ]
107+
108+ /// Extracts name introduced by `NamedDeclSyntax` node.
109+ private static func handle( namedDecl: NamedDeclSyntax , accessibleAfter: AbsolutePosition ? = nil ) -> [ LookupName ] {
110+ [ . declaration( namedDecl, accessibleAfter: accessibleAfter) ]
140111 }
141112}
0 commit comments