Skip to content

Commit 0f9b2bc

Browse files
committed
Add implicit Self to extension declaration scope. Fix name introduction of a variable with accessors in global scope. Add suggested changes and documentation.
1 parent 433f14b commit 0f9b2bc

File tree

4 files changed

+38
-17
lines changed

4 files changed

+38
-17
lines changed

Sources/SwiftLexicalLookup/LookupName.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import SwiftSyntax
2020
case `self`(DeclSyntaxProtocol)
2121
/// `Self` keyword representing object type.
2222
/// Could be associated with type declaration or extension.
23-
case `Self`(ProtocolDeclSyntax)
23+
case `Self`(DeclSyntaxProtocol)
2424
/// `error` value caught by a `catch`
2525
/// block that does not specify a catch pattern.
2626
case error(CatchClauseSyntax)
@@ -147,27 +147,33 @@ import SwiftSyntax
147147
case .identifier(let syntax, _):
148148
return syntax.identifier.positionAfterSkippingLeadingTrivia
149149
case .declaration(let syntax):
150-
return syntax.name.position
150+
return syntax.name.positionAfterSkippingLeadingTrivia
151151
case .implicit(let implicitName):
152152
switch implicitName {
153153
case .self(let declSyntax):
154154
switch Syntax(declSyntax).as(SyntaxEnum.self) {
155155
case .functionDecl(let functionDecl):
156-
return functionDecl.name.position
156+
return functionDecl.name.positionAfterSkippingLeadingTrivia
157157
case .initializerDecl(let initializerDecl):
158158
return initializerDecl.initKeyword.positionAfterSkippingLeadingTrivia
159159
case .subscriptDecl(let subscriptDecl):
160-
return subscriptDecl.accessorBlock?.position ?? subscriptDecl.endPosition
160+
return subscriptDecl.accessorBlock?.positionAfterSkippingLeadingTrivia
161+
?? subscriptDecl.endPositionBeforeTrailingTrivia
161162
case .variableDecl(let variableDecl):
162163
return variableDecl.bindings.first?.accessorBlock?.positionAfterSkippingLeadingTrivia
163164
?? variableDecl.endPosition
164165
default:
165166
return declSyntax.positionAfterSkippingLeadingTrivia
166167
}
167-
case .Self(let protocolDecl):
168-
return protocolDecl.name.positionAfterSkippingLeadingTrivia
168+
case .Self(let declSyntax):
169+
switch Syntax(declSyntax).as(SyntaxEnum.self) {
170+
case .protocolDecl(let protocolDecl):
171+
return protocolDecl.name.positionAfterSkippingLeadingTrivia
172+
default:
173+
return declSyntax.positionAfterSkippingLeadingTrivia
174+
}
169175
case .error(let catchClause):
170-
return catchClause.body.position
176+
return catchClause.body.positionAfterSkippingLeadingTrivia
171177
default:
172178
return implicitName.syntax.positionAfterSkippingLeadingTrivia
173179
}

Sources/SwiftLexicalLookup/Scopes/CanInterleaveResultsLaterScopeSyntax.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import SwiftSyntax
1414

1515
protocol CanInterleaveResultsLaterScopeSyntax: ScopeSyntax {
16+
/// Perform lookup in this scope and later introduce results
17+
/// passed as `resultsToInterleave`.
18+
/// The exact behavior depends on a specific scope.
1619
func lookupWithInterleavedResults(
1720
_ identifier: Identifier?,
1821
at lookUpPosition: AbsolutePosition,

Sources/SwiftLexicalLookup/Scopes/ScopeImplementations.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,13 @@ import SwiftSyntax
498498
with config: LookupConfig
499499
) -> [LookupResult] {
500500
if memberBlock.range.contains(lookUpPosition) {
501-
return [.lookInMembers(self)] + defaultLookupImplementation(identifier, at: lookUpPosition, with: config)
501+
let implicitSelf: [LookupName] = [.implicit(.Self(self))]
502+
.filter { name in
503+
checkIdentifier(identifier, refersTo: name, at: lookUpPosition)
504+
}
505+
506+
return (implicitSelf.isEmpty ? [] : [.fromScope(self, withNames: implicitSelf)]) + [.lookInMembers(self)]
507+
+ defaultLookupImplementation(identifier, at: lookUpPosition, with: config)
502508
} else {
503509
return defaultLookupImplementation(identifier, at: lookUpPosition, with: config)
504510
}
@@ -665,13 +671,16 @@ import SwiftSyntax
665671
)
666672
}
667673

674+
let lookInMembers: [LookupResult] =
675+
inheritanceClause?.range.contains(lookUpPosition) ?? false ? [] : [.lookInMembers(self)]
676+
668677
return results
669678
+ defaultLookupImplementation(
670679
identifier,
671680
at: lookUpPosition,
672681
with: config,
673682
propagateToParent: false
674-
) + [.lookInMembers(self)] + lookupInParent(identifier, at: lookUpPosition, with: config)
683+
) + lookInMembers + lookupInParent(identifier, at: lookUpPosition, with: config)
675684
}
676685
}
677686

@@ -868,12 +877,11 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
868877
at lookUpPosition: AbsolutePosition,
869878
with config: LookupConfig
870879
) -> [LookupResult] {
871-
if let parentScope,
872-
parentScope.is(MemberBlockSyntax.self),
873-
bindings.first?.accessorBlock?.range.contains(lookUpPosition) ?? false
874-
{
880+
if bindings.first?.accessorBlock?.range.contains(lookUpPosition) ?? false {
881+
let shouldIntroduceSelf = parentScope?.is(MemberBlockSyntax.self) ?? false
882+
875883
return defaultLookupImplementation(
876-
in: [.implicit(.self(self))],
884+
in: LookupName.getNames(from: self) + (shouldIntroduceSelf ? [.implicit(.self(self))] : []),
877885
identifier,
878886
at: lookUpPosition,
879887
with: config
@@ -883,14 +891,16 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe
883891
}
884892
}
885893

894+
/// If a member, introduce results passed in `resultsToInterleave`
895+
/// and then pass lookup to the parent. Otherwise, perform `lookup`.
886896
func lookupWithInterleavedResults(
887897
_ identifier: Identifier?,
888898
at lookUpPosition: AbsolutePosition,
889899
with config: LookupConfig,
890900
resultsToInterleave: [LookupResult]
891901
) -> [LookupResult] {
892902
guard parentScope?.is(MemberBlockSyntax.self) ?? false else {
893-
return lookupInParent(identifier, at: lookUpPosition, with: config)
903+
return lookup(identifier, at: lookUpPosition, with: config)
894904
}
895905

896906
return resultsToInterleave + lookupInParent(identifier, at: lookUpPosition, with: config)

Tests/SwiftLexicalLookupTest/NameLookupTests.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ final class testNameLookup: XCTestCase {
660660
func testImplicitSelf() {
661661
assertLexicalNameLookup(
662662
source: """
663-
extension a {
663+
7️⃣extension a {
664664
struct b {
665665
2️⃣func foo() {
666666
let x: 3️⃣Self = 4️⃣self
@@ -675,6 +675,7 @@ final class testNameLookup: XCTestCase {
675675
references: [
676676
"3️⃣": [
677677
.lookInMembers(StructDeclSyntax.self),
678+
.fromScope(ExtensionDeclSyntax.self, expectedNames: [NameExpectation.implicit(.Self("7️⃣"))]),
678679
.lookInMembers(ExtensionDeclSyntax.self),
679680
],
680681
"4️⃣": [
@@ -683,7 +684,8 @@ final class testNameLookup: XCTestCase {
683684
.lookInMembers(ExtensionDeclSyntax.self),
684685
],
685686
"5️⃣": [
686-
.lookInMembers(ExtensionDeclSyntax.self)
687+
.fromScope(ExtensionDeclSyntax.self, expectedNames: [NameExpectation.implicit(.Self("7️⃣"))]),
688+
.lookInMembers(ExtensionDeclSyntax.self),
687689
],
688690
"6️⃣": [
689691
.fromScope(FunctionDeclSyntax.self, expectedNames: [NameExpectation.implicit(.self("1️⃣"))]),

0 commit comments

Comments
 (0)