Skip to content

Commit e15bfaa

Browse files
committed
Format.
1 parent 5519ccb commit e15bfaa

File tree

5 files changed

+97
-13
lines changed

5 files changed

+97
-13
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
@_spi(Experimental) public protocol IntroducingToParentScopeSyntax: ScopeSyntax {
16+
func introducedToParent(
17+
for name: String?,
18+
at syntax: SyntaxProtocol,
19+
with configDict: LookupConfigDictionary
20+
) -> [LookupResult]
21+
}

Sources/SwiftLexicalLookup/LookupName.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,6 @@ import SwiftSyntax
9191
functionCallExpr.arguments.flatMap { argument in
9292
getNames(from: argument.expression, accessibleAfter: accessibleAfter)
9393
}
94-
case .guardStmt(let guardStmt):
95-
guardStmt.conditions.flatMap { cond in
96-
getNames(from: cond.condition, accessibleAfter: cond.endPosition)
97-
}
9894
default:
9995
if let namedDecl = Syntax(syntax).asProtocol(SyntaxProtocol.self) as? NamedDeclSyntax {
10096
handle(namedDecl: namedDecl, accessibleAfter: accessibleAfter)

Sources/SwiftLexicalLookup/ScopeImplementations.swift

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ extension SyntaxProtocol {
6767

6868
let names = introducedNames(using: nameIntroductionStrategy)
6969
.filter { introducedName in
70-
introducedName.isAccessible(at: syntax) && (name == nil || introducedName.refersTo(name!))
70+
does(name: name, referTo: introducedName, at: syntax)
7171
}
7272

73-
return [.fromFileScope(self, withNames: names, nameIntroductionStrategy: nameIntroductionStrategy)]
73+
return names.isEmpty
74+
? [] : [.fromFileScope(self, withNames: names, nameIntroductionStrategy: nameIntroductionStrategy)]
7475
}
7576
}
7677

@@ -80,6 +81,45 @@ extension SyntaxProtocol {
8081
LookupName.getNames(from: codeBlockItem.item, accessibleAfter: codeBlockItem.endPosition)
8182
}
8283
}
84+
85+
public func lookup(
86+
for name: String?,
87+
at syntax: SyntaxProtocol,
88+
with configDict: LookupConfigDictionary
89+
) -> [LookupResult] {
90+
var result = [LookupResult]()
91+
var currentChunk = [LookupName]()
92+
93+
for codeBlockItem in statements {
94+
if let introducingToParentScope = Syntax(codeBlockItem.item).asProtocol(SyntaxProtocol.self)
95+
as? IntroducingToParentScopeSyntax
96+
{
97+
if !currentChunk.isEmpty {
98+
result.append(.fromScope(self, withNames: currentChunk))
99+
currentChunk = []
100+
}
101+
102+
result.append(contentsOf: introducingToParentScope.introducedToParent(for: name, at: syntax, with: configDict))
103+
} else {
104+
currentChunk.append(
105+
contentsOf:
106+
LookupName.getNames(
107+
from: codeBlockItem.item,
108+
accessibleAfter: codeBlockItem.endPosition
109+
).filter { introducedName in
110+
does(name: name, referTo: introducedName, at: syntax)
111+
}
112+
)
113+
}
114+
}
115+
116+
if !currentChunk.isEmpty {
117+
result.append(.fromScope(self, withNames: currentChunk))
118+
currentChunk = []
119+
}
120+
121+
return result.reversed() + lookupInParent(for: name, at: syntax, with: configDict)
122+
}
83123
}
84124

85125
@_spi(Experimental) extension ForStmtSyntax: ScopeSyntax {
@@ -171,7 +211,21 @@ extension SyntaxProtocol {
171211
}
172212
}
173213

174-
@_spi(Experimental) extension GuardStmtSyntax: ScopeSyntax {
214+
@_spi(Experimental) extension GuardStmtSyntax: IntroducingToParentScopeSyntax {
215+
public func introducedToParent(
216+
for name: String?,
217+
at syntax: SwiftSyntax.SyntaxProtocol,
218+
with configDict: LookupConfigDictionary
219+
) -> [LookupResult] {
220+
let names = conditions.flatMap { element in
221+
LookupName.getNames(from: element.condition, accessibleAfter: element.endPosition)
222+
}.filter { introducedName in
223+
does(name: name, referTo: introducedName, at: syntax)
224+
}
225+
226+
return names.isEmpty ? [] : [.fromScope(self, withNames: names)]
227+
}
228+
175229
public var introducedNames: [LookupName] {
176230
[]
177231
}
@@ -182,7 +236,7 @@ extension SyntaxProtocol {
182236
with configDict: LookupConfigDictionary
183237
) -> [LookupResult] {
184238
if body.position <= syntax.position && body.endPosition >= syntax.position {
185-
lookupInParent(for: name, at: self, with: configDict)
239+
lookupInParent(for: name, at: self, with: configDict) // Should we add a new config that will skip certain scopes in lookup? Could be more consistent.
186240
} else {
187241
defaultLookupImplementation(for: name, at: syntax, with: configDict)
188242
}

Sources/SwiftLexicalLookup/ScopeSyntax.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ extension SyntaxProtocol {
8585
let filteredNames =
8686
introducedNames
8787
.filter { introducedName in
88-
introducedName.isAccessible(at: syntax) && (name == nil || introducedName.refersTo(name!))
88+
does(name: name, referTo: introducedName, at: syntax)
8989
}
9090

9191
if filteredNames.isEmpty {
@@ -103,4 +103,8 @@ extension SyntaxProtocol {
103103
) -> [LookupResult] {
104104
parentScope?.lookup(for: name, at: syntax, with: configDict) ?? []
105105
}
106+
107+
func does(name: String?, referTo introducedName: LookupName, at syntax: SyntaxProtocol) -> Bool {
108+
introducedName.isAccessible(at: syntax) && (name == nil || introducedName.refersTo(name!))
109+
}
106110
}

Tests/SwiftLexicalLookupTest/NameLookupTests.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,11 @@ final class testNameLookup: XCTestCase {
440440
references: [
441441
"4️⃣": [.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣"])],
442442
"5️⃣": [],
443-
"6️⃣": [.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣", "2️⃣"])],
444-
"7️⃣": [.fromScope(CodeBlockSyntax.self, expectedNames: ["3️⃣"])],
443+
"6️⃣": [
444+
.fromScope(GuardStmtSyntax.self, expectedNames: ["2️⃣"]),
445+
.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣"]),
446+
],
447+
"7️⃣": [.fromScope(GuardStmtSyntax.self, expectedNames: ["3️⃣"])],
445448
],
446449
expectedResultTypes: .all(
447450
IdentifierPatternSyntax.self
@@ -459,8 +462,14 @@ final class testNameLookup: XCTestCase {
459462
""",
460463
references: [
461464
"3️⃣": [.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣"])],
462-
"5️⃣": [.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣", "2️⃣"])],
463-
"6️⃣": [.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣", "2️⃣", "4️⃣"])],
465+
"5️⃣": [
466+
.fromScope(GuardStmtSyntax.self, expectedNames: ["2️⃣"]),
467+
.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣"]),
468+
],
469+
"6️⃣": [
470+
.fromScope(GuardStmtSyntax.self, expectedNames: ["2️⃣", "4️⃣"]),
471+
.fromScope(CodeBlockSyntax.self, expectedNames: ["1️⃣"]),
472+
],
464473
],
465474
expectedResultTypes: .all(
466475
IdentifierPatternSyntax.self

0 commit comments

Comments
 (0)