13
13
import SwiftDiagnostics
14
14
import SwiftSyntax
15
15
16
+ /// Describes all of the #if/#elseif/#else clauses within the given syntax node,
17
+ /// indicating their active state. This operation will recurse into all
18
+ /// clauses to indicate regions of active / inactive / unparsed code.
19
+ ///
20
+ /// For example, given code like the following:
21
+ /// #if DEBUG
22
+ /// #if A
23
+ /// func f()
24
+ /// #elseif B
25
+ /// func g()
26
+ /// #elseif compiler(>= 12.0)
27
+ /// please print the number after 41
28
+ /// #endif
29
+ /// #else
30
+ /// #endif
31
+ ///
32
+ /// If the configuration options `DEBUG` and `B` are provided, but `A` is not,
33
+ /// and the compiler version is less than 12.0, the results will be contain:
34
+ /// - Active region for the `#if DEBUG`.
35
+ /// - Inactive region for the `#if A`.
36
+ /// - Active region for the `#elseif B`.
37
+ /// - Unparsed region for the `#elseif compiler(>= 12.0)`.
38
+ /// - Inactive region for the final `#else`.
39
+ public struct ConfiguredRegions {
40
+ let regions : [ Element ]
41
+
42
+ /// The set of diagnostics produced when evaluating the configured regions.
43
+ public let diagnostics : [ Diagnostic ]
44
+
45
+ /// Determine whether the given syntax node is active within the configured
46
+ /// regions.
47
+ public func isActive( _ node: some SyntaxProtocol ) -> IfConfigRegionState {
48
+ var currentState : IfConfigRegionState = . active
49
+ for (ifClause, state) in regions {
50
+ if node. position < ifClause. position {
51
+ return currentState
52
+ }
53
+
54
+ if node. position <= ifClause. endPosition {
55
+ currentState = state
56
+ }
57
+ }
58
+
59
+ return currentState
60
+ }
61
+ }
62
+
63
+ extension ConfiguredRegions : RandomAccessCollection {
64
+ public typealias Element = ( IfConfigClauseSyntax , IfConfigRegionState )
65
+ public var startIndex : Int { regions. startIndex }
66
+ public var endIndex : Int { regions. endIndex }
67
+
68
+ public subscript( index: Int ) -> Element {
69
+ regions [ index]
70
+ }
71
+ }
72
+
16
73
extension SyntaxProtocol {
17
74
/// Find all of the #if/#elseif/#else clauses within the given syntax node,
18
75
/// indicating their active state. This operation will recurse into all
@@ -39,10 +96,13 @@ extension SyntaxProtocol {
39
96
/// - Inactive region for the final `#else`.
40
97
public func configuredRegions(
41
98
in configuration: some BuildConfiguration
42
- ) -> [ ( IfConfigClauseSyntax , IfConfigRegionState ) ] {
99
+ ) -> ConfiguredRegions {
43
100
let visitor = ConfiguredRegionVisitor ( configuration: configuration)
44
101
visitor. walk ( self )
45
- return visitor. regions
102
+ return ConfiguredRegions (
103
+ regions: visitor. regions,
104
+ diagnostics: visitor. diagnostics
105
+ )
46
106
}
47
107
}
48
108
0 commit comments