Skip to content

Commit 2bff318

Browse files
committed
Eliminate the outermostCondition parameter of #if evaluation
Instead of passing state down for `#if` evaluation, walk up the syntax tree to compute the same information.
1 parent 9f421e5 commit 2bff318

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

Sources/SwiftIfConfig/IfConfigEvaluation.swift

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ import SwiftSyntax
3030
/// diagnose syntax errors in blocks where the check fails.
3131
func evaluateIfConfig(
3232
condition: ExprSyntax,
33-
configuration: some BuildConfiguration,
34-
outermostCondition: Bool = true
33+
configuration: some BuildConfiguration
3534
) -> (active: Bool, syntaxErrorsAllowed: Bool, diagnostics: [Diagnostic]) {
3635
var extraDiagnostics: [Diagnostic] = []
3736

@@ -115,8 +114,7 @@ func evaluateIfConfig(
115114

116115
let (innerActive, innerSyntaxErrorsAllowed, innerDiagnostics) = evaluateIfConfig(
117116
condition: prefixOp.expression,
118-
configuration: configuration,
119-
outermostCondition: outermostCondition
117+
configuration: configuration
120118
)
121119

122120
return (active: !innerActive, syntaxErrorsAllowed: innerSyntaxErrorsAllowed, diagnostics: innerDiagnostics)
@@ -133,7 +131,7 @@ func evaluateIfConfig(
133131
}
134132

135133
// Check whether this was likely to be a check for targetEnvironment(simulator).
136-
if outermostCondition,
134+
if binOp.isOutermostIfCondition,
137135
let targetEnvironmentDiag = diagnoseLikelySimulatorEnvironmentTest(binOp)
138136
{
139137
extraDiagnostics.append(targetEnvironmentDiag)
@@ -142,8 +140,7 @@ func evaluateIfConfig(
142140
// Evaluate the left-hand side.
143141
let (lhsActive, lhsSyntaxErrorsAllowed, lhsDiagnostics) = evaluateIfConfig(
144142
condition: binOp.leftOperand,
145-
configuration: configuration,
146-
outermostCondition: false
143+
configuration: configuration
147144
)
148145

149146
// Determine whether we already know the result. We might short-circuit the
@@ -176,14 +173,12 @@ func evaluateIfConfig(
176173
if shortCircuitResult != nil {
177174
(rhsActive, rhsSyntaxErrorsAllowed, rhsDiagnostics) = evaluateIfConfig(
178175
condition: binOp.rightOperand,
179-
configuration: CanImportSuppressingBuildConfiguration(other: configuration),
180-
outermostCondition: false
176+
configuration: CanImportSuppressingBuildConfiguration(other: configuration)
181177
)
182178
} else {
183179
(rhsActive, rhsSyntaxErrorsAllowed, rhsDiagnostics) = evaluateIfConfig(
184180
condition: binOp.rightOperand,
185-
configuration: configuration,
186-
outermostCondition: false
181+
configuration: configuration
187182
)
188183
}
189184

@@ -213,8 +208,7 @@ func evaluateIfConfig(
213208
{
214209
return evaluateIfConfig(
215210
condition: element.expression,
216-
configuration: configuration,
217-
outermostCondition: outermostCondition
211+
configuration: configuration
218212
)
219213
}
220214

@@ -504,6 +498,31 @@ func evaluateIfConfig(
504498
return recordError(.unknownExpression(condition))
505499
}
506500

501+
extension SyntaxProtocol {
502+
/// Determine whether this expression node is an "outermost" #if condition,
503+
/// meaning that it is not nested within some kind of expression like && or
504+
/// ||.
505+
fileprivate var isOutermostIfCondition: Bool {
506+
// If there is no parent, it's the outermost condition.
507+
guard let parent = self.parent else {
508+
return true
509+
}
510+
511+
// If we hit the #if condition clause, it's the outermost condition.
512+
if parent.is(IfConfigClauseSyntax.self) {
513+
return true
514+
}
515+
516+
// We found an infix operator, so this is not an outermost #if condition.
517+
if parent.is(InfixOperatorExprSyntax.self) {
518+
return false
519+
}
520+
521+
// Keep looking up the syntax tree.
522+
return parent.isOutermostIfCondition
523+
}
524+
}
525+
507526
/// Given an expression with the expected form A.B.C, extract the import path
508527
/// ["A", "B", "C"] from it. Throws an error if the expression doesn't match
509528
/// this form.

0 commit comments

Comments
 (0)