Skip to content

Commit 433f14b

Browse files
committed
Add suggested changes. Add new specialized scope: CanInterleaveResultsLaterScopeSyntax.
1 parent 3de7208 commit 433f14b

File tree

6 files changed

+97
-34
lines changed

6 files changed

+97
-34
lines changed

Sources/SwiftLexicalLookup/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_swift_syntax_library(SwiftLexicalLookup
1515
Configurations/FileScopeHandlingConfig.swift
1616
Configurations/LookupConfig.swift
1717

18+
Scopes/CanInterleaveResultsLaterScopeSyntax.swift
1819
Scopes/FunctionScopeSyntax.swift
1920
Scopes/GenericParameterScopeSyntax.swift
2021
Scopes/IntroducingToSequentialParentScopeSyntax.swift

Sources/SwiftLexicalLookup/Configurations/LookupConfig.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,43 @@
1414
/// Specifies behavior of file scope.
1515
@_spi(Experimental) public var fileScopeHandling: FileScopeHandlingConfig
1616
/// Specifies whether lookup should finish in the closest sequential scope.
17+
///
18+
/// ### Example
19+
/// ```swift
20+
/// class X {
21+
/// let a = 42
22+
///
23+
/// func (a: Int) {
24+
/// let a = 123
25+
///
26+
/// a // <-- lookup here
27+
/// }
28+
/// }
29+
/// ```
30+
/// When looking up at the specified position with `finishInSequentialScope`
31+
/// set to `false`, lookup will return declaration from inside function body,
32+
/// function parameter and the `a` declaration from `class X` member block.
33+
/// If `finishInSequentialScope` would be set to `false`, the only name
34+
/// returned by lookup would be the `a` declaration from inside function body.
1735
@_spi(Experimental) public var finishInSequentialScope: Bool
1836
/// Specifies whether to include results generated in file and member block scopes.
37+
///
38+
/// ### Example
39+
/// ```swift
40+
/// class X {
41+
/// let a = 42
42+
///
43+
/// func (a: Int) {
44+
/// let a = 123
45+
///
46+
/// a // <-- lookup here
47+
/// }
48+
/// }
49+
/// ```
50+
/// When looking up at the specified position with `includeMembers`
51+
/// set to `true`, lookup will return declaration from inside function body,
52+
/// function parameter and the `a` declaration from `class X` member block.
53+
/// If `includeMembers` would be set to `false`, the latter name would be omitted.
1954
@_spi(Experimental) public var includeMembers: Bool
2055

2156
/// Creates a new lookup configuration.

Sources/SwiftLexicalLookup/LookupName.swift

Lines changed: 4 additions & 9 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`(DeclSyntaxProtocol)
23+
case `Self`(ProtocolDeclSyntax)
2424
/// `error` value caught by a `catch`
2525
/// block that does not specify a catch pattern.
2626
case error(CatchClauseSyntax)
@@ -164,13 +164,8 @@ import SwiftSyntax
164164
default:
165165
return declSyntax.positionAfterSkippingLeadingTrivia
166166
}
167-
case .Self(let declSyntax):
168-
switch Syntax(declSyntax).as(SyntaxEnum.self) {
169-
case .protocolDecl(let protocolDecl):
170-
return protocolDecl.name.positionAfterSkippingLeadingTrivia
171-
default:
172-
return declSyntax.positionAfterSkippingLeadingTrivia
173-
}
167+
case .Self(let protocolDecl):
168+
return protocolDecl.name.positionAfterSkippingLeadingTrivia
174169
case .error(let catchClause):
175170
return catchClause.body.position
176171
default:
@@ -271,7 +266,7 @@ import SwiftSyntax
271266
@_spi(Experimental) public var debugDescription: String {
272267
let sourceLocationConverter = SourceLocationConverter(fileName: "", tree: syntax.root)
273268
let location = sourceLocationConverter.location(for: position)
274-
let strName = (identifier != nil ? identifier!.name : "NO-NAME") + " at: \(location.line):\(location.column)"
269+
let strName = (identifier?.name ?? "NO-NAME") + " at: \(location.line):\(location.column)"
275270

276271
switch self {
277272
case .identifier:

Sources/SwiftLexicalLookup/LookupResult.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,6 @@ import SwiftSyntax
9494
@_spi(Experimental) extension [LookupResult] {
9595
/// Debug description this array of lookup results.
9696
@_spi(Experimental) public var debugDescription: String {
97-
var str: String = ""
98-
99-
for (index, result) in self.enumerated() {
100-
str += result.debugDescription + (index + 1 == self.count ? "" : "\n")
101-
}
102-
103-
return str
97+
return self.map(\.debugDescription).joined(separator: "\n")
10498
}
10599
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
15+
protocol CanInterleaveResultsLaterScopeSyntax: ScopeSyntax {
16+
func lookupWithInterleavedResults(
17+
_ identifier: Identifier?,
18+
at lookUpPosition: AbsolutePosition,
19+
with config: LookupConfig,
20+
resultsToInterleave: [LookupResult]
21+
) -> [LookupResult]
22+
}

Sources/SwiftLexicalLookup/Scopes/ScopeImplementations.swift

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -508,22 +508,18 @@ import SwiftSyntax
508508
@_spi(Experimental) extension AccessorDeclSyntax: ScopeSyntax {
509509
/// Implicit and/or explicit names introduced within the accessor.
510510
@_spi(Experimental) public var introducedNames: [LookupName] {
511-
let names: [LookupName]
512-
513511
if let parameters {
514-
names = LookupName.getNames(from: parameters)
512+
return LookupName.getNames(from: parameters)
515513
} else {
516514
switch accessorSpecifier.tokenKind {
517515
case .keyword(.set), .keyword(.willSet):
518-
names = [.implicit(.newValue(self))]
516+
return [.implicit(.newValue(self))]
519517
case .keyword(.didSet):
520-
names = [.implicit(.oldValue(self))]
518+
return [.implicit(.oldValue(self))]
521519
default:
522-
names = []
520+
return []
523521
}
524522
}
525-
526-
return names
527523
}
528524

529525
@_spi(Experimental) public var scopeDebugName: String {
@@ -539,7 +535,10 @@ import SwiftSyntax
539535
at lookUpPosition: AbsolutePosition,
540536
with config: LookupConfig
541537
) -> [LookupResult] {
542-
guard let parentAccessorBlockScope = parentScope?.as(AccessorBlockSyntax.self) else {
538+
guard let parentScope,
539+
let canInterleaveLaterScope = Syntax(parentScope).asProtocol(SyntaxProtocol.self)
540+
as? CanInterleaveResultsLaterScopeSyntax
541+
else {
543542
return defaultLookupImplementation(identifier, at: lookUpPosition, with: config)
544543
}
545544

@@ -554,7 +553,7 @@ import SwiftSyntax
554553
with: config,
555554
propagateToParent: false
556555
)
557-
+ parentAccessorBlockScope.interleaveAccessorResultsAfterSubscriptLookup(
556+
+ canInterleaveLaterScope.lookupWithInterleavedResults(
558557
identifier,
559558
at: lookUpPosition,
560559
with: config,
@@ -701,7 +700,8 @@ import SwiftSyntax
701700
}
702701
}
703702

704-
@_spi(Experimental) extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax {
703+
@_spi(Experimental)
704+
extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveResultsLaterScopeSyntax {
705705
/// Parameters introduced by this subscript and possibly `self` keyword.
706706
@_spi(Experimental) public var introducedNames: [LookupName] {
707707
let parameters = parameterClause.parameters.flatMap { parameter in
@@ -726,7 +726,7 @@ import SwiftSyntax
726726
at lookUpPosition: AbsolutePosition,
727727
with config: LookupConfig
728728
) -> [LookupResult] {
729-
interleaveResultsAfterThisSubscriptLookup(
729+
lookupWithInterleavedResults(
730730
identifier,
731731
at: lookUpPosition,
732732
with: config,
@@ -753,7 +753,7 @@ import SwiftSyntax
753753
/// introduced at the boundary of the getter. That's why
754754
/// this function needs to ensure the implicit `self` passed
755755
/// from inside the accessor block is added after `subscript` parameters.
756-
func interleaveResultsAfterThisSubscriptLookup(
756+
func lookupWithInterleavedResults(
757757
_ identifier: Identifier?,
758758
at lookUpPosition: AbsolutePosition,
759759
with config: LookupConfig,
@@ -779,7 +779,7 @@ import SwiftSyntax
779779
}
780780
}
781781

782-
@_spi(Experimental) extension AccessorBlockSyntax: SequentialScopeSyntax {
782+
@_spi(Experimental) extension AccessorBlockSyntax: SequentialScopeSyntax, CanInterleaveResultsLaterScopeSyntax {
783783
/// Names from the accessors or
784784
/// getters of this accessor block scope.
785785
@_spi(Experimental) public var introducedNames: [LookupName] {
@@ -815,17 +815,20 @@ import SwiftSyntax
815815

816816
/// Used by children accessors to interleave
817817
/// their results with parent `subscript` declaration scope.
818-
func interleaveAccessorResultsAfterSubscriptLookup(
818+
func lookupWithInterleavedResults(
819819
_ identifier: Identifier?,
820820
at lookUpPosition: AbsolutePosition,
821821
with config: LookupConfig,
822822
resultsToInterleave: [LookupResult]
823823
) -> [LookupResult] {
824-
guard let parentSubscriptScope = parentScope?.as(SubscriptDeclSyntax.self) else {
824+
guard let parentScope,
825+
let canInterleaveLaterScope = Syntax(parentScope).asProtocol(SyntaxProtocol.self)
826+
as? CanInterleaveResultsLaterScopeSyntax
827+
else {
825828
return lookupInParent(identifier, at: lookUpPosition, with: config)
826829
}
827830

828-
return parentSubscriptScope.interleaveResultsAfterThisSubscriptLookup(
831+
return canInterleaveLaterScope.lookupWithInterleavedResults(
829832
identifier,
830833
at: lookUpPosition,
831834
with: config,
@@ -845,7 +848,7 @@ import SwiftSyntax
845848
}
846849
}
847850

848-
@_spi(Experimental) extension VariableDeclSyntax: ScopeSyntax {
851+
@_spi(Experimental) extension VariableDeclSyntax: CanInterleaveResultsLaterScopeSyntax {
849852
/// Variable decl scope doesn't introduce any
850853
/// names unless it is a member and is looked
851854
/// up from inside it's accessor block.
@@ -879,4 +882,17 @@ import SwiftSyntax
879882
return lookupInParent(identifier, at: lookUpPosition, with: config)
880883
}
881884
}
885+
886+
func lookupWithInterleavedResults(
887+
_ identifier: Identifier?,
888+
at lookUpPosition: AbsolutePosition,
889+
with config: LookupConfig,
890+
resultsToInterleave: [LookupResult]
891+
) -> [LookupResult] {
892+
guard parentScope?.is(MemberBlockSyntax.self) ?? false else {
893+
return lookupInParent(identifier, at: lookUpPosition, with: config)
894+
}
895+
896+
return resultsToInterleave + lookupInParent(identifier, at: lookUpPosition, with: config)
897+
}
882898
}

0 commit comments

Comments
 (0)