77
88/// Determines whether a value can be considered `true` at compile time.
99struct IsStaticallyTrue : ExprSyntaxVisitor {
10- let allowOnOff : Bool
10+ /// If `true`, text of `on, off, yes and no` are valid values.
11+ let allowOnOffYesNo : Bool
1112
12- mutating func visit( _ expr: borrowing BindParameterSyntax ) -> Bool { false }
13+ private( set) var diagnostics = Diagnostics ( )
14+
15+ mutating func isTrue( _ expr: ExprSyntax ) -> Bool {
16+ return expr. accept ( visitor: & self )
17+ }
18+
19+ mutating func visit( _ expr: borrowing BindParameterSyntax ) -> Bool {
20+ emitNotBoolDiag ( for: expr)
21+ return false
22+ }
1323
1424 mutating func visit( _ expr: borrowing ColumnExprSyntax ) -> Bool {
15- guard allowOnOff, expr. schema == nil , expr. table == nil else {
16- return false
17- }
18-
19- switch expr. column. value. uppercased ( ) {
20- case " ON " : return true
21- case " OFF " : return false
22- default :
23- return false
24- }
25+ return false
2526 }
2627
27- mutating func visit( _ expr: borrowing PrefixExprSyntax ) -> Bool { false }
28+ mutating func visit( _ expr: borrowing PrefixExprSyntax ) -> Bool {
29+ emitNotBoolDiag ( for: expr)
30+ return false
31+ }
2832
29- mutating func visit( _ expr: borrowing InfixExprSyntax ) -> Bool { false }
33+ mutating func visit( _ expr: borrowing InfixExprSyntax ) -> Bool {
34+ emitNotBoolDiag ( for: expr)
35+ return false
36+ }
3037
31- mutating func visit( _ expr: borrowing PostfixExprSyntax ) -> Bool { false }
38+ mutating func visit( _ expr: borrowing PostfixExprSyntax ) -> Bool {
39+ emitNotBoolDiag ( for: expr)
40+ return false
41+ }
3242
33- mutating func visit( _ expr: borrowing BetweenExprSyntax ) -> Bool { false }
43+ mutating func visit( _ expr: borrowing BetweenExprSyntax ) -> Bool {
44+ emitNotBoolDiag ( for: expr)
45+ return false
46+ }
3447
35- mutating func visit( _ expr: borrowing FunctionExprSyntax ) -> Bool { false }
48+ mutating func visit( _ expr: borrowing FunctionExprSyntax ) -> Bool {
49+ emitNotBoolDiag ( for: expr)
50+ return false
51+ }
3652
37- mutating func visit( _ expr: borrowing CastExprSyntax ) -> Bool { false }
53+ mutating func visit( _ expr: borrowing CastExprSyntax ) -> Bool {
54+ emitNotBoolDiag ( for: expr)
55+ return false
56+ }
3857
39- mutating func visit( _ expr: borrowing CaseWhenThenExprSyntax ) -> Bool { false }
58+ mutating func visit( _ expr: borrowing CaseWhenThenExprSyntax ) -> Bool {
59+ emitNotBoolDiag ( for: expr)
60+ return false
61+ }
4062
41- mutating func visit( _ expr: borrowing GroupedExprSyntax ) -> Bool { false }
63+ mutating func visit( _ expr: borrowing GroupedExprSyntax ) -> Bool {
64+ emitNotBoolDiag ( for: expr)
65+ return false
66+ }
4267
43- mutating func visit( _ expr: borrowing SelectExprSyntax ) -> Bool { false }
68+ mutating func visit( _ expr: borrowing SelectExprSyntax ) -> Bool {
69+ emitNotBoolDiag ( for: expr)
70+ return false
71+ }
4472
45- mutating func visit( _ expr: borrowing InvalidExprSyntax ) -> Bool { false }
73+ mutating func visit( _ expr: borrowing InvalidExprSyntax ) -> Bool {
74+ emitNotBoolDiag ( for: expr)
75+ return false
76+ }
4677
4778 mutating func visit( _ expr: borrowing LiteralExprSyntax ) -> Bool {
4879 switch expr. kind {
@@ -52,8 +83,29 @@ struct IsStaticallyTrue: ExprSyntaxVisitor {
5283 return true
5384 case . false :
5485 return false
86+ case . string( let text) :
87+ guard allowOnOffYesNo else {
88+ emitNotBoolDiag ( for: expr)
89+ return false
90+ }
91+
92+ switch text. uppercased ( ) {
93+ case " YES " , " ON " : return true
94+ case " NO " , " OFF " : return false
95+ default :
96+ emitNotBoolDiag ( for: expr)
97+ return false
98+ }
5599 default :
100+ emitNotBoolDiag ( for: expr)
56101 return false
57102 }
58103 }
104+
105+ private mutating func emitNotBoolDiag< S: Syntax > ( for syntax: S ) {
106+ diagnostics. add ( . init(
107+ " Value is not a static boolean, expected TRUE, FALSE, 1 or 0 " ,
108+ at: syntax. range
109+ ) )
110+ }
59111}
0 commit comments