Skip to content

Commit 01f2887

Browse files
committed
Add suggestions
1 parent be2e588 commit 01f2887

File tree

10 files changed

+138
-154
lines changed

10 files changed

+138
-154
lines changed

Sources/SwiftLexicalLookup/IntroducingToSequentialParentScopeSyntax.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
import SwiftSyntax
1414

1515
protocol IntroducingToSequentialParentScopeSyntax: ScopeSyntax {
16-
/// Returns names matching lookup that should be
17-
/// handled by it's parent sequential scope.
18-
func introducesToSequentialParent(
16+
/// Returns all names introduced to parent.
17+
var namesIntroducedToSequentialParent: [LookupName] { get }
18+
19+
/// Returns results matching lookup that should be
20+
/// interleaved with results of the sequential parent.
21+
func lookupFromSequentialParent(
1922
for identifier: Identifier?,
20-
at origin: SyntaxProtocol,
21-
with config: LookupConfig,
22-
state: LookupState
23+
at origin: AbsolutePosition,
24+
with config: LookupConfig
2325
) -> [LookupResult]
2426
}

Sources/SwiftLexicalLookup/LookupName.swift

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ import SwiftSyntax
6161
}
6262
}
6363

64-
/// Identifier used for name comparison.
64+
/// Note that `self` and `Self` are treated as identifiers for name lookup purposes
65+
/// and that a variable named `self` can shadow the `self` keyword. For example.
6566
///
6667
///
6768
/// ```swift
@@ -82,11 +83,21 @@ import SwiftSyntax
8283
/// abc
8384
/// def
8485
/// ```
85-
/// `self` and `Self` identifers override
86-
/// implicit `self` and `Self` introduced by
86+
/// `self` and `Self` identifers override implicit `self` and `Self` introduced by
8787
/// the `Foo` class declaration.
8888
var identifier: Identifier {
89-
Identifier(name)
89+
switch self {
90+
case .self:
91+
return Identifier("self")
92+
case .Self:
93+
return Identifier("Self")
94+
case .error:
95+
return Identifier("error")
96+
case .newValue:
97+
return Identifier("newValue")
98+
case .oldValue:
99+
return Identifier("oldValue")
100+
}
90101
}
91102
}
92103

@@ -99,6 +110,10 @@ import SwiftSyntax
99110
case declaration(NamedDeclSyntax)
100111
/// Name introduced implicitly by certain syntax nodes.
101112
case implicit(ImplicitDecl)
113+
/// Explicit `self` keyword.
114+
case `self`(IdentifiableSyntax, accessibleAfter: AbsolutePosition?)
115+
/// Explicit `Self` keyword.
116+
case `Self`(IdentifiableSyntax, accessibleAfter: AbsolutePosition?)
102117

103118
/// Syntax associated with this name.
104119
@_spi(Experimental) public var syntax: SyntaxProtocol {
@@ -109,36 +124,44 @@ import SwiftSyntax
109124
return syntax
110125
case .implicit(let implicitName):
111126
return implicitName.syntax
127+
case .self(let syntax, _), .Self(let syntax, _):
128+
return syntax
112129
}
113130
}
114131

115132
/// Identifier used for name comparison.
116133
@_spi(Experimental) public var identifier: Identifier? {
117134
switch self {
118135
case .identifier(let syntax, _):
119-
return Identifier(syntax.identifier) ?? Identifier(syntax.identifier.text)
136+
return Identifier(syntax.identifier)
120137
case .declaration(let syntax):
121138
return Identifier(syntax.name)
122139
case .implicit(let kind):
123140
return kind.identifier
141+
case .self:
142+
return Identifier("self")
143+
case .Self:
144+
return Identifier("Self")
124145
}
125146
}
126147

127148
/// Point, after which the name is available in scope.
128149
/// If set to `nil`, the name is available at any point in scope.
129150
var accessibleAfter: AbsolutePosition? {
130151
switch self {
131-
case .identifier(_, let absolutePosition):
152+
case .identifier(_, let absolutePosition),
153+
.self(_, let absolutePosition),
154+
.Self(_, let absolutePosition):
132155
return absolutePosition
133156
default:
134157
return nil
135158
}
136159
}
137160

138161
/// Checks if this name was introduced before the syntax used for lookup.
139-
func isAccessible(at lookedUpSyntax: SyntaxProtocol) -> Bool {
162+
func isAccessible(at origin: AbsolutePosition) -> Bool {
140163
guard let accessibleAfter else { return true }
141-
return accessibleAfter <= lookedUpSyntax.position
164+
return accessibleAfter <= origin
142165
}
143166

144167
/// Checks if this name refers to the looked up phrase.
@@ -205,10 +228,17 @@ import SwiftSyntax
205228
identifiable: IdentifiableSyntax,
206229
accessibleAfter: AbsolutePosition? = nil
207230
) -> [LookupName] {
208-
if identifiable.identifier.tokenKind != .wildcard {
209-
return [.identifier(identifiable, accessibleAfter: accessibleAfter)]
210-
} else {
211-
return []
231+
switch identifiable.identifier.tokenKind {
232+
case .keyword(.self):
233+
return [.self(identifiable, accessibleAfter: accessibleAfter)]
234+
case .keyword(.Self):
235+
return [.Self(identifiable, accessibleAfter: accessibleAfter)]
236+
default:
237+
if identifiable.identifier.tokenKind != .wildcard {
238+
return [.identifier(identifiable, accessibleAfter: accessibleAfter)]
239+
} else {
240+
return []
241+
}
212242
}
213243
}
214244

Sources/SwiftLexicalLookup/LookupState.swift

Lines changed: 0 additions & 19 deletions
This file was deleted.

Sources/SwiftLexicalLookup/ScopeImplementations.swift

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ import SwiftSyntax
9696
/// - for `memberBlockUpToLastDecl` - a, b, c, d
9797
/// - for `memberBlock` - a, b, c, d, e, f
9898
/// - for `codeBlock` - a
99-
@_spi(Experimental) public func _lookup(
99+
@_spi(Experimental) public func lookup(
100100
for identifier: Identifier?,
101-
at origin: SyntaxProtocol,
102-
with config: LookupConfig,
103-
state: LookupState
101+
at origin: AbsolutePosition,
102+
with config: LookupConfig
104103
) -> [LookupResult] {
105104
switch config.fileScopeHandling {
106105
case .memberBlock:
@@ -121,7 +120,7 @@ import SwiftSyntax
121120
if encounteredNonDeclaration {
122121
sequentialItems.append(codeBlockItem)
123122
} else {
124-
if item.is(DeclSyntax.self) || item.is(VariableDeclSyntax.self) {
123+
if item.is(DeclSyntax.self) {
125124
let foundNames = LookupName.getNames(from: item)
126125

127126
members.append(contentsOf: foundNames.filter { checkName(identifier, refersTo: $0, at: origin) })
@@ -137,7 +136,6 @@ import SwiftSyntax
137136
for: identifier,
138137
at: origin,
139138
with: config,
140-
state: state,
141139
createResultsForThisScopeWith: { .fromFileScope(self, withNames: $0) }
142140
)
143141

@@ -155,18 +153,16 @@ import SwiftSyntax
155153
}
156154
}
157155

158-
@_spi(Experimental) public func _lookup(
156+
@_spi(Experimental) public func lookup(
159157
for identifier: Identifier?,
160-
at origin: SyntaxProtocol,
161-
with config: LookupConfig,
162-
state: LookupState
158+
at origin: AbsolutePosition,
159+
with config: LookupConfig
163160
) -> [LookupResult] {
164161
sequentialLookup(
165162
in: statements,
166163
for: identifier,
167164
at: origin,
168165
with: config,
169-
state: state,
170166
createResultsForThisScopeWith: { .fromScope(self, withNames: $0) }
171167
)
172168
}
@@ -277,16 +273,15 @@ import SwiftSyntax
277273
/// // <-- a is not visible here
278274
/// }
279275
/// ```
280-
@_spi(Experimental) public func _lookup(
276+
@_spi(Experimental) public func lookup(
281277
for identifier: Identifier?,
282-
at origin: SyntaxProtocol,
283-
with config: LookupConfig,
284-
state: LookupState
278+
at origin: AbsolutePosition,
279+
with config: LookupConfig
285280
) -> [LookupResult] {
286-
if let elseBody, elseBody.position <= origin.position, elseBody.endPosition >= origin.position {
287-
return lookupInParent(for: identifier, at: origin, with: config, state: state)
281+
if let elseBody, elseBody.position <= origin, elseBody.endPosition >= origin {
282+
return lookupInParent(for: identifier, at: origin, with: config)
288283
} else {
289-
return defaultLookupImplementation(for: identifier, at: origin, with: config, state: state)
284+
return defaultLookupImplementation(for: identifier, at: origin, with: config)
290285
}
291286
}
292287
}
@@ -301,8 +296,19 @@ import SwiftSyntax
301296
}
302297

303298
@_spi(Experimental) extension GuardStmtSyntax: IntroducingToSequentialParentScopeSyntax {
304-
/// Returns names matching lookup.
305-
/// Lookup triggered from inside of `else`
299+
var namesIntroducedToSequentialParent: [LookupName] {
300+
conditions.flatMap { element in
301+
LookupName.getNames(from: element.condition, accessibleAfter: element.endPosition)
302+
}
303+
}
304+
305+
@_spi(Experimental) public var introducedNames: [LookupName] {
306+
[]
307+
}
308+
309+
/// Returns results matching lookup that should be
310+
/// interleaved with sequential parent's results.
311+
/// Lookup triggered from within of the `else` body
306312
/// returns no names.
307313
///
308314
/// Example:
@@ -312,27 +318,20 @@ import SwiftSyntax
312318
/// }
313319
/// // a is visible here
314320
/// ```
315-
@_spi(Experimental) public func introducesToSequentialParent(
321+
func lookupFromSequentialParent(
316322
for identifier: Identifier?,
317-
at origin: SyntaxProtocol,
318-
with config: LookupConfig,
319-
state: LookupState
323+
at origin: AbsolutePosition,
324+
with config: LookupConfig
320325
) -> [LookupResult] {
321-
guard body.position > origin.position || body.endPosition < origin.position
326+
guard body.position > origin || body.endPosition < origin
322327
else { return [] }
323328

324-
let names = conditions.flatMap { element in
325-
LookupName.getNames(from: element.condition, accessibleAfter: element.endPosition)
326-
}.filter { introducedName in
329+
let names = namesIntroducedToSequentialParent.filter { introducedName in
327330
checkName(identifier, refersTo: introducedName, at: origin)
328331
}
329332

330333
return names.isEmpty ? [] : [.fromScope(self, withNames: names)]
331334
}
332-
333-
@_spi(Experimental) public var introducedNames: [LookupName] {
334-
[]
335-
}
336335
}
337336

338337
@_spi(Experimental) extension ActorDeclSyntax: TypeScopeSyntax {}
@@ -342,8 +341,7 @@ import SwiftSyntax
342341
@_spi(Experimental) extension ExtensionDeclSyntax: TypeScopeSyntax {}
343342

344343
@_spi(Experimental) extension AccessorDeclSyntax: ScopeSyntax {
345-
/// Implicit and/or explicit names introduced
346-
/// within the accessor.
344+
/// Implicit and/or explicit names introduced within the accessor.
347345
@_spi(Experimental) public var introducedNames: [LookupName] {
348346
if let parameters {
349347
return LookupName.getNames(from: parameters)

Sources/SwiftLexicalLookup/ScopeSyntax.swift

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extension SyntaxProtocol {
4747
for identifier: Identifier?,
4848
with config: LookupConfig = LookupConfig()
4949
) -> [LookupResult] {
50-
scope?.lookup(for: identifier, at: self, with: config) ?? []
50+
scope?.lookup(for: identifier, at: self.position, with: config) ?? []
5151
}
5252
}
5353

@@ -59,13 +59,10 @@ extension SyntaxProtocol {
5959
/// Finds all declarations `identifier` refers to. `syntax` specifies the node lookup was triggered with.
6060
/// If `identifier` set to `nil`, returns all available names at the given node.
6161
/// `state` represents lookup state passed between lookup methods.
62-
///
63-
/// - Note: This method is intended for internal use only. For public usage, use ``ScopeSyntax/lookup(for:at:with:)`` instead.
64-
func _lookup(
62+
func lookup(
6563
for identifier: Identifier?,
66-
at origin: SyntaxProtocol,
67-
with config: LookupConfig,
68-
state: LookupState
64+
at origin: AbsolutePosition,
65+
with config: LookupConfig
6966
) -> [LookupResult]
7067
}
7168

@@ -78,36 +75,21 @@ extension SyntaxProtocol {
7875
/// refers to and is accessible at given syntax node then passes lookup to the parent.
7976
/// If `identifier` set to `nil`, returns all available names at the given node.
8077
/// `state` represents lookup state passed between lookup methods.
81-
///
82-
/// - Note: This method is intended for internal use only. For public usage, use ``ScopeSyntax/lookup(for:at:with:)`` instead.
83-
@_spi(Experimental) public func _lookup(
84-
for identifier: Identifier?,
85-
at origin: SyntaxProtocol,
86-
with config: LookupConfig,
87-
state: LookupState
88-
) -> [LookupResult] {
89-
defaultLookupImplementation(for: identifier, at: origin, with: config, state: state)
90-
}
91-
92-
/// Returns `LookupResult` of all names introduced in this scope that `identifier`
93-
/// refers to and is accessible at given syntax node then passes lookup to the parent.
94-
/// If `identifier` set to `nil`, returns all available names at the given node.
9578
@_spi(Experimental) public func lookup(
9679
for identifier: Identifier?,
97-
at origin: SyntaxProtocol,
80+
at origin: AbsolutePosition,
9881
with config: LookupConfig
9982
) -> [LookupResult] {
100-
_lookup(for: identifier, at: origin, with: config, state: LookupState())
83+
defaultLookupImplementation(for: identifier, at: origin, with: config)
10184
}
10285

10386
/// Returns `LookupResult` of all names introduced in this scope that `identifier`
10487
/// refers to and is accessible at given syntax node then passes lookup to the parent.
10588
/// If `identifier` set to `nil`, returns all available names at the given node.
10689
func defaultLookupImplementation(
10790
for identifier: Identifier?,
108-
at origin: SyntaxProtocol,
109-
with config: LookupConfig,
110-
state: LookupState
91+
at origin: AbsolutePosition,
92+
with config: LookupConfig
11193
) -> [LookupResult] {
11294
let filteredNames =
11395
introducedNames
@@ -116,24 +98,23 @@ extension SyntaxProtocol {
11698
}
11799

118100
if filteredNames.isEmpty {
119-
return lookupInParent(for: identifier, at: origin, with: config, state: state)
101+
return lookupInParent(for: identifier, at: origin, with: config)
120102
} else {
121103
return [.fromScope(self, withNames: filteredNames)]
122-
+ lookupInParent(for: identifier, at: origin, with: config, state: state)
104+
+ lookupInParent(for: identifier, at: origin, with: config)
123105
}
124106
}
125107

126108
/// Looks up in parent scope.
127109
func lookupInParent(
128110
for identifier: Identifier?,
129-
at origin: SyntaxProtocol,
130-
with config: LookupConfig,
131-
state: LookupState
111+
at origin: AbsolutePosition,
112+
with config: LookupConfig
132113
) -> [LookupResult] {
133-
parentScope?._lookup(for: identifier, at: origin, with: config, state: state) ?? []
114+
parentScope?.lookup(for: identifier, at: origin, with: config) ?? []
134115
}
135116

136-
func checkName(_ name: Identifier?, refersTo introducedName: LookupName, at origin: SyntaxProtocol) -> Bool {
117+
func checkName(_ name: Identifier?, refersTo introducedName: LookupName, at origin: AbsolutePosition) -> Bool {
137118
introducedName.isAccessible(at: origin) && (name == nil || introducedName.refersTo(name!))
138119
}
139120
}

0 commit comments

Comments
 (0)