-
Notifications
You must be signed in to change notification settings - Fork 501
Expand file tree
/
Copy pathEnumCaseDeclSyntax.swift
More file actions
71 lines (63 loc) · 2.63 KB
/
EnumCaseDeclSyntax.swift
File metadata and controls
71 lines (63 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftSyntax
@_spi(Experimental) extension EnumCaseDeclSyntax: ScopeSyntax {
/// Associated-value parameter names introduced by this case declaration.
///
/// Names are position-gated and only visible inside default-value expressions
/// of subsequent parameters within the same case element, e.g.:
/// ```swift
/// enum E {
/// case foo(x: Int, y: Int = x) // `x` visible in `y`'s default
/// }
/// ```
/// Parameters from one case element are not visible inside another.
@_spi(Experimental) public var defaultIntroducedNames: [LookupName] {
elements.flatMap { element in
element.parameterClause?.parameters.flatMap { param in
LookupName.getNames(from: param)
} ?? []
}
}
@_spi(Experimental) public var scopeDebugName: String {
"EnumCaseDeclScope"
}
/// Looks up `identifier` from inside this case declaration.
///
/// Only introduces names when lookup originates from a parameter's
/// default-value expression. Names visible are those of all prior
/// parameters within the same case element.
///
/// Lookup from outside the declaration (e.g. in the enum body) is
/// forwarded to the parent scope with no names introduced.
@_spi(Experimental) public func lookup(
_ identifier: Identifier?,
at lookUpPosition: AbsolutePosition,
with config: LookupConfig
) -> [LookupResult] {
for element in elements {
guard let paramClause = element.parameterClause else { continue }
for (index, param) in paramClause.parameters.enumerated() {
guard let defaultValue = param.defaultValue,
defaultValue.range.contains(lookUpPosition)
else { continue }
// Collect names from params before this one in the same element.
let priorNames = paramClause.parameters.prefix(index).flatMap { prior in
LookupName.getNames(from: prior)
}.filter { $0.refersTo(identifier) }
return LookupResult.getResultArray(for: self, withNames: priorNames)
+ lookupInParent(identifier, at: lookUpPosition, with: config)
}
}
return lookupInParent(identifier, at: lookUpPosition, with: config)
}
}