@@ -15,34 +15,46 @@ import SwiftSyntax
15
15
@_spi ( Experimental) public enum LookupName {
16
16
/// Identifier associated with the name.
17
17
/// Could be an identifier of a variable, function or closure parameter and more
18
- case identifier( String , SyntaxProtocol )
18
+ case identifier( IdentifiableSyntax , accessibleAfter : AbsolutePosition ? )
19
19
/// Declaration associated with the name.
20
20
/// Could be class, struct, actor, protocol, function and more
21
- case declaration( String , DeclSyntaxProtocol )
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
- case . identifier( _ , let syntax) :
26
+ case . identifier( let syntax, _ ) :
27
27
syntax
28
- case . declaration( _ , let syntax) :
28
+ case . declaration( let syntax, _ ) :
29
29
syntax
30
30
}
31
31
}
32
32
33
33
/// Introduced name.
34
34
@_spi ( Experimental) public var name : String {
35
35
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
40
51
}
41
52
}
42
53
43
54
/// 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
46
58
}
47
59
48
60
/// Checks if this name refers to the looked up phrase.
@@ -51,91 +63,50 @@ import SwiftSyntax
51
63
}
52
64
53
65
/// 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 ] {
55
67
switch Syntax ( syntax) . as ( SyntaxEnum . self) {
56
68
case . variableDecl( let variableDecl) :
57
69
variableDecl. bindings. flatMap { binding in
58
- getNames ( from: binding. pattern)
70
+ getNames ( from: binding. pattern, accessibleAfter : accessibleAfter )
59
71
}
60
72
case . tuplePattern( let tuplePattern) :
61
73
tuplePattern. elements. flatMap { tupleElement in
62
- getNames ( from: tupleElement. pattern)
74
+ getNames ( from: tupleElement. pattern, accessibleAfter : accessibleAfter )
63
75
}
64
76
case . valueBindingPattern( let valueBindingPattern) :
65
- getNames ( from: valueBindingPattern. pattern)
77
+ getNames ( from: valueBindingPattern. pattern, accessibleAfter : accessibleAfter )
66
78
case . expressionPattern( let expressionPattern) :
67
- getNames ( from: expressionPattern. expression)
79
+ getNames ( from: expressionPattern. expression, accessibleAfter : accessibleAfter )
68
80
case . sequenceExpr( let sequenceExpr) :
69
81
sequenceExpr. elements. flatMap { expression in
70
- getNames ( from: expression)
82
+ getNames ( from: expression, accessibleAfter : accessibleAfter )
71
83
}
72
84
case . patternExpr( let patternExpr) :
73
- getNames ( from: patternExpr. pattern)
85
+ getNames ( from: patternExpr. pattern, accessibleAfter : accessibleAfter )
74
86
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)
92
88
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
+ }
94
96
}
95
97
}
96
98
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) ]
112
103
} else {
113
104
return [ ]
114
105
}
115
106
}
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) ]
140
111
}
141
112
}
0 commit comments