Skip to content

Commit 539b1d7

Browse files
committed
Add suggested changes.
1 parent 5705b96 commit 539b1d7

File tree

9 files changed

+159
-117
lines changed

9 files changed

+159
-117
lines changed

Sources/SwiftLexicalLookup/IntroducingToSequentialParentScopeSyntax.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protocol IntroducingToSequentialParentScopeSyntax: ScopeSyntax {
1717
/// handled by it's parent sequential scope.
1818
func introducesToSequentialParent(
1919
for identifier: Identifier?,
20-
at syntax: SyntaxProtocol,
20+
at origin: SyntaxProtocol,
2121
with config: LookupConfig,
2222
state: LookupState
2323
) -> [LookupResult]

Sources/SwiftLexicalLookup/LookupName.swift

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212

1313
import SwiftSyntax
1414

15-
@_spi(Experimental) public enum LookupImplicitNameKind {
15+
/// An entity that is implicitly declared based on the syntactic structure of the program.
16+
@_spi(Experimental) public enum ImplicitDecl {
1617
/// `self` keyword representing object instance.
17-
case `self`(SyntaxProtocol)
18+
/// Could be associated with type declaration, extension,
19+
/// or closure captures.
20+
case `self`(DeclSyntaxProtocol)
1821
/// `Self` keyword representing object type.
22+
/// Could be associated with type declaration or extension.
1923
case `Self`(DeclSyntaxProtocol)
20-
/// `self` captured by a closure.
24+
/// `error` value caught by a `catch`
25+
/// block that does not specify a catch pattern.
2126
case error(CatchClauseSyntax)
2227
/// `newValue` available by default inside `set` and `willSet`.
2328
case newValue(AccessorDeclSyntax)
@@ -28,35 +33,58 @@ import SwiftSyntax
2833
@_spi(Experimental) public var syntax: SyntaxProtocol {
2934
switch self {
3035
case .self(let syntax):
31-
syntax
36+
return syntax
3237
case .Self(let syntax):
33-
syntax
38+
return syntax
3439
case .error(let syntax):
35-
syntax
40+
return syntax
3641
case .newValue(let syntax):
37-
syntax
42+
return syntax
3843
case .oldValue(let syntax):
39-
syntax
44+
return syntax
4045
}
4146
}
4247

43-
/// Name associated with implicit name kind.
48+
/// The name of the implicit declaration.
4449
private var name: String {
4550
switch self {
4651
case .self:
47-
"self"
52+
return "self"
4853
case .Self:
49-
"Self"
54+
return "Self"
5055
case .error:
51-
"error"
56+
return "error"
5257
case .newValue:
53-
"newValue"
58+
return "newValue"
5459
case .oldValue:
55-
"oldValue"
60+
return "oldValue"
5661
}
5762
}
5863

5964
/// Identifier used for name comparison.
65+
///
66+
///
67+
/// ```swift
68+
/// class Foo {
69+
/// func test() {
70+
/// let `Self` = "abc"
71+
/// print(Self.self)
72+
///
73+
/// let `self` = "def"
74+
/// print(self)
75+
/// }
76+
/// }
77+
///
78+
/// Foo().test()
79+
/// ```
80+
/// prints:
81+
/// ```
82+
/// abc
83+
/// def
84+
/// ```
85+
/// `self` and `Self` identifers override
86+
/// implicit `self` and `Self` introduced by
87+
/// the `Foo` class declaration.
6088
var identifier: Identifier {
6189
Identifier(name)
6290
}
@@ -70,29 +98,29 @@ import SwiftSyntax
7098
/// Could be class, struct, actor, protocol, function and more.
7199
case declaration(NamedDeclSyntax)
72100
/// Name introduced implicitly by certain syntax nodes.
73-
case implicit(LookupImplicitNameKind)
101+
case implicit(ImplicitDecl)
74102

75103
/// Syntax associated with this name.
76104
@_spi(Experimental) public var syntax: SyntaxProtocol {
77105
switch self {
78106
case .identifier(let syntax, _):
79-
syntax
107+
return syntax
80108
case .declaration(let syntax):
81-
syntax
109+
return syntax
82110
case .implicit(let implicitName):
83-
implicitName.syntax
111+
return implicitName.syntax
84112
}
85113
}
86114

87115
/// Identifier used for name comparison.
88116
@_spi(Experimental) public var identifier: Identifier? {
89117
switch self {
90118
case .identifier(let syntax, _):
91-
Identifier(syntax.identifier)
119+
return Identifier(syntax.identifier) ?? Identifier(syntax.identifier.text)
92120
case .declaration(let syntax):
93-
Identifier(syntax.name)
121+
return Identifier(syntax.name)
94122
case .implicit(let kind):
95-
kind.identifier
123+
return kind.identifier
96124
}
97125
}
98126

@@ -177,11 +205,7 @@ import SwiftSyntax
177205
identifiable: IdentifiableSyntax,
178206
accessibleAfter: AbsolutePosition? = nil
179207
) -> [LookupName] {
180-
if let closureCapture = identifiable as? ClosureCaptureSyntax,
181-
closureCapture.identifier.tokenKind == .keyword(.self)
182-
{
183-
return [.implicit(.self(closureCapture))] // Handle `self` closure capture.
184-
} else if identifiable.identifier.tokenKind != .wildcard {
208+
if identifiable.identifier.tokenKind != .wildcard {
185209
return [.identifier(identifiable, accessibleAfter: accessibleAfter)]
186210
} else {
187211
return []

Sources/SwiftLexicalLookup/LookupState.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import Foundation
1414

15+
/// Represents internal state for lookup.
16+
/// It shouldn't be used by clients.
1517
@_spi(Experimental) public struct LookupState {
1618
/// Specifies scopes that introduce names to their parent and
1719
/// should be skipped during lookup in sequential scopes.

Sources/SwiftLexicalLookup/ScopeImplementations.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,21 @@ import SwiftSyntax
9898
/// - for `codeBlock` - a
9999
@_spi(Experimental) public func _lookup(
100100
for identifier: Identifier?,
101-
at syntax: SyntaxProtocol,
101+
at origin: SyntaxProtocol,
102102
with config: LookupConfig,
103103
state: LookupState
104104
) -> [LookupResult] {
105105
switch config.fileScopeHandling {
106106
case .memberBlock:
107107
let names = introducedNames(using: .memberBlock)
108108
.filter { lookupName in
109-
checkName(identifier, refersTo: lookupName, at: syntax)
109+
checkName(identifier, refersTo: lookupName, at: origin)
110110
}
111111

112112
return names.isEmpty ? [] : [.fromFileScope(self, withNames: names)]
113113
case .memberBlockUpToLastDecl:
114-
var members = [LookupName]()
115-
var sequentialItems = [CodeBlockItemSyntax]()
114+
var members: [LookupName] = []
115+
var sequentialItems: [CodeBlockItemSyntax] = []
116116
var encounteredNonDeclaration = false
117117

118118
for codeBlockItem in statements {
@@ -124,7 +124,7 @@ import SwiftSyntax
124124
if item.is(DeclSyntax.self) || item.is(VariableDeclSyntax.self) {
125125
let foundNames = LookupName.getNames(from: item)
126126

127-
members.append(contentsOf: foundNames.filter { checkName(identifier, refersTo: $0, at: syntax) })
127+
members.append(contentsOf: foundNames.filter { checkName(identifier, refersTo: $0, at: origin) })
128128
} else {
129129
encounteredNonDeclaration = true
130130
sequentialItems.append(codeBlockItem)
@@ -135,7 +135,7 @@ import SwiftSyntax
135135
let sequentialNames = sequentialLookup(
136136
in: sequentialItems,
137137
for: identifier,
138-
at: syntax,
138+
at: origin,
139139
with: config,
140140
state: state,
141141
createResultsForThisScopeWith: { .fromFileScope(self, withNames: $0) }
@@ -157,14 +157,14 @@ import SwiftSyntax
157157

158158
@_spi(Experimental) public func _lookup(
159159
for identifier: Identifier?,
160-
at syntax: SyntaxProtocol,
160+
at origin: SyntaxProtocol,
161161
with config: LookupConfig,
162162
state: LookupState
163163
) -> [LookupResult] {
164164
sequentialLookup(
165165
in: statements,
166166
for: identifier,
167-
at: syntax,
167+
at: origin,
168168
with: config,
169169
state: state,
170170
createResultsForThisScopeWith: { .fromScope(self, withNames: $0) }
@@ -279,14 +279,14 @@ import SwiftSyntax
279279
/// ```
280280
@_spi(Experimental) public func _lookup(
281281
for identifier: Identifier?,
282-
at syntax: SyntaxProtocol,
282+
at origin: SyntaxProtocol,
283283
with config: LookupConfig,
284284
state: LookupState
285285
) -> [LookupResult] {
286-
if let elseBody, elseBody.position <= syntax.position, elseBody.endPosition >= syntax.position {
287-
return lookupInParent(for: identifier, at: syntax, with: config, state: state)
286+
if let elseBody, elseBody.position <= origin.position, elseBody.endPosition >= origin.position {
287+
return lookupInParent(for: identifier, at: origin, with: config, state: state)
288288
} else {
289-
return defaultLookupImplementation(for: identifier, at: syntax, with: config, state: state)
289+
return defaultLookupImplementation(for: identifier, at: origin, with: config, state: state)
290290
}
291291
}
292292
}
@@ -303,14 +303,14 @@ import SwiftSyntax
303303
@_spi(Experimental) extension GuardStmtSyntax: IntroducingToSequentialParentScopeSyntax {
304304
@_spi(Experimental) public func introducesToSequentialParent(
305305
for identifier: Identifier?,
306-
at syntax: SwiftSyntax.SyntaxProtocol,
306+
at origin: SyntaxProtocol,
307307
with config: LookupConfig,
308308
state: LookupState
309309
) -> [LookupResult] {
310310
let names = conditions.flatMap { element in
311311
LookupName.getNames(from: element.condition, accessibleAfter: element.endPosition)
312312
}.filter { introducedName in
313-
checkName(identifier, refersTo: introducedName, at: syntax)
313+
checkName(identifier, refersTo: introducedName, at: origin)
314314
}
315315

316316
return names.isEmpty ? [] : [.fromScope(self, withNames: names)]
@@ -333,16 +333,16 @@ import SwiftSyntax
333333
/// ```
334334
@_spi(Experimental) public func _lookup(
335335
for identifier: Identifier?,
336-
at syntax: SyntaxProtocol,
336+
at origin: SyntaxProtocol,
337337
with config: LookupConfig,
338338
state: LookupState
339339
) -> [LookupResult] {
340-
if body.position <= syntax.position && body.endPosition >= syntax.position {
340+
if body.position <= origin.position && body.endPosition >= origin.position {
341341
var newState = state
342342
newState.skipSequentialIntroductionFrom = self
343-
return lookupInParent(for: identifier, at: syntax, with: config, state: newState)
343+
return lookupInParent(for: identifier, at: origin, with: config, state: newState)
344344
} else {
345-
return defaultLookupImplementation(for: identifier, at: syntax, with: config, state: state)
345+
return defaultLookupImplementation(for: identifier, at: origin, with: config, state: state)
346346
}
347347
}
348348
}

Sources/SwiftLexicalLookup/ScopeSyntax.swift

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,14 @@ extension SyntaxProtocol {
5656
var parentScope: ScopeSyntax? { get }
5757
/// Names found in this scope. Ordered from first to last introduced.
5858
var introducedNames: [LookupName] { get }
59-
/// Finds all declarations `name` refers to. `syntax` specifies the node lookup was triggered with.
60-
/// If `name` set to `nil`, returns all available names at the given node.
61-
func lookup(
62-
for identifier: Identifier?,
63-
at syntax: SyntaxProtocol,
64-
with config: LookupConfig
65-
) -> [LookupResult]
66-
/// Finds all declarations `name` refers to. `syntax` specifies the node lookup was triggered with.
67-
/// If `name` set to `nil`, returns all available names at the given node.
59+
/// Finds all declarations `identifier` refers to. `syntax` specifies the node lookup was triggered with.
60+
/// If `identifier` set to `nil`, returns all available names at the given node.
6861
/// `state` represents lookup state passed between lookup methods.
6962
///
7063
/// - Note: This method is intended for internal use only. For public usage, use ``ScopeSyntax/lookup(for:at:with:)`` instead.
7164
func _lookup(
7265
for identifier: Identifier?,
73-
at syntax: SyntaxProtocol,
66+
at origin: SyntaxProtocol,
7467
with config: LookupConfig,
7568
state: LookupState
7669
) -> [LookupResult]
@@ -81,66 +74,66 @@ extension SyntaxProtocol {
8174
self.parent?.scope
8275
}
8376

84-
/// Returns `LookupResult` of all names introduced in this scope that `name`
77+
/// Returns `LookupResult` of all names introduced in this scope that `identifier`
8578
/// refers to and is accessible at given syntax node then passes lookup to the parent.
86-
/// If `name` set to `nil`, returns all available names at the given node.
79+
/// If `identifier` set to `nil`, returns all available names at the given node.
8780
/// `state` represents lookup state passed between lookup methods.
8881
///
8982
/// - Note: This method is intended for internal use only. For public usage, use ``ScopeSyntax/lookup(for:at:with:)`` instead.
9083
@_spi(Experimental) public func _lookup(
9184
for identifier: Identifier?,
92-
at syntax: SyntaxProtocol,
85+
at origin: SyntaxProtocol,
9386
with config: LookupConfig,
9487
state: LookupState
9588
) -> [LookupResult] {
96-
defaultLookupImplementation(for: identifier, at: syntax, with: config, state: state)
89+
defaultLookupImplementation(for: identifier, at: origin, with: config, state: state)
9790
}
98-
99-
/// Returns `LookupResult` of all names introduced in this scope that `name`
91+
92+
/// Returns `LookupResult` of all names introduced in this scope that `identifier`
10093
/// refers to and is accessible at given syntax node then passes lookup to the parent.
101-
/// If `name` set to `nil`, returns all available names at the given node.
94+
/// If `identifier` set to `nil`, returns all available names at the given node.
10295
@_spi(Experimental) public func lookup(
10396
for identifier: Identifier?,
104-
at syntax: SyntaxProtocol,
97+
at origin: SyntaxProtocol,
10598
with config: LookupConfig
10699
) -> [LookupResult] {
107-
_lookup(for: identifier, at: syntax, with: config, state: LookupState())
100+
_lookup(for: identifier, at: origin, with: config, state: LookupState())
108101
}
109102

110-
/// Returns `LookupResult` of all names introduced in this scope that `name`
103+
/// Returns `LookupResult` of all names introduced in this scope that `identifier`
111104
/// refers to and is accessible at given syntax node then passes lookup to the parent.
112-
/// If `name` set to `nil`, returns all available names at the given node.
105+
/// If `identifier` set to `nil`, returns all available names at the given node.
113106
func defaultLookupImplementation(
114107
for identifier: Identifier?,
115-
at syntax: SyntaxProtocol,
108+
at origin: SyntaxProtocol,
116109
with config: LookupConfig,
117110
state: LookupState
118111
) -> [LookupResult] {
119112
let filteredNames =
120113
introducedNames
121114
.filter { introducedName in
122-
checkName(identifier, refersTo: introducedName, at: syntax)
115+
checkName(identifier, refersTo: introducedName, at: origin)
123116
}
124117

125118
if filteredNames.isEmpty {
126-
return lookupInParent(for: identifier, at: syntax, with: config, state: state)
119+
return lookupInParent(for: identifier, at: origin, with: config, state: state)
127120
} else {
128121
return [.fromScope(self, withNames: filteredNames)]
129-
+ lookupInParent(for: identifier, at: syntax, with: config, state: state)
122+
+ lookupInParent(for: identifier, at: origin, with: config, state: state)
130123
}
131124
}
132125

133126
/// Looks up in parent scope.
134127
func lookupInParent(
135128
for identifier: Identifier?,
136-
at syntax: SyntaxProtocol,
129+
at origin: SyntaxProtocol,
137130
with config: LookupConfig,
138131
state: LookupState
139132
) -> [LookupResult] {
140-
parentScope?._lookup(for: identifier, at: syntax, with: config, state: state) ?? []
133+
parentScope?._lookup(for: identifier, at: origin, with: config, state: state) ?? []
141134
}
142135

143-
func checkName(_ name: Identifier?, refersTo introducedName: LookupName, at syntax: SyntaxProtocol) -> Bool {
144-
introducedName.isAccessible(at: syntax) && (name == nil || introducedName.refersTo(name!))
136+
func checkName(_ name: Identifier?, refersTo introducedName: LookupName, at origin: SyntaxProtocol) -> Bool {
137+
introducedName.isAccessible(at: origin) && (name == nil || introducedName.refersTo(name!))
145138
}
146139
}

0 commit comments

Comments
 (0)