-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathdiag_constantness_check_os_log.swift
228 lines (188 loc) · 7.7 KB
/
diag_constantness_check_os_log.swift
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
// RUN: %target-typecheck-verify-swift -swift-version 5
// REQUIRES: VENDOR=apple
// Tests the constantness Sema diagnostics for the OSLogTestHelper module,
// which acts as a stub for the os overlay.
import OSLogTestHelper
func testDynamicLogMessage(message: OSLogMessage) {
_osLogTestHelper(message)
// expected-error@-1 {{argument must be a string interpolation}}
}
func testNonconstantFormatOption(
formatOpt: OSLogIntegerFormatting,
explicitPositiveSign: Bool) {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
let uppercase = true
_osLogTestHelper("\(UInt.max, format: .hex(uppercase: uppercase))")
// expected-error@-1 {{argument must be a bool literal}}
_osLogTestHelper("\(UInt.max, format: .hex)") // No error is expected here.
}
func testNonconstantPrivacyOption(privacyOpt: OSLogPrivacy) {
_osLogTestHelper("Integer: \(Int.max, privacy: privacyOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogPrivacy'}}
}
func testNonconstantAlignmentOption(alignOpt: OSLogStringAlignment) {
_osLogTestHelper("Integer: \(Int.max, align: alignOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogStringAlignment'}}
}
func testMultipleOptions(
formatOpt: OSLogIntegerFormatting,
privacyOpt: OSLogPrivacy
) {
_osLogTestHelper(
"""
\(2, format: formatOpt, align: .right(columns: 10), privacy: privacyOpt)
""")
// expected-error@-2 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
// expected-error@-3 {{argument must be a static method or property of 'OSLogPrivacy'}}
}
func testNoninlinedOSLogMessage() {
let logMessage: OSLogMessage = "Minimum integer value: \(Int.min)"
_osLogTestHelper(logMessage)
// expected-error@-1 {{argument must be a string interpolation}}
}
let globalLogMessage: OSLogMessage = "A global message"
func testGlobalLogMessage() {
_osLogTestHelper(globalLogMessage)
// expected-error@-1 {{argument must be a string interpolation}}
}
// No errors are expected here.
func testValidLogCalls(x: Int) {
_osLogTestHelper("\(x, format: .hex, privacy: .private)")
_osLogTestHelper("\(x, format: OSLogIntegerFormatting.hex, privacy: .public)")
_osLogTestHelper("\(x, privacy: OSLogPrivacy.public)")
_osLogTestHelper("\((x + 1) * 2, privacy: .public)")
}
// Check whether os-log-specific diagnostics do not crash when there
// are type errors.
func testTypeIncorrectLogCalls() {
let message = "test message"
class TestClass {
}
let x = TestClass()
_osLogTestHelper(message)
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'OSLogMessage'}}
_osLogTestHelper("prefix" + "\(x)")
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'OSLogMessage'}}
_osLogTestHelper("prefix", "\(x)")
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type '(String, UnsafeBufferPointer<UInt8>) -> Void'}}
// expected-error@-2 {{missing argument label 'assertion:' in call}}
_osLogTestHelper("\(x, format: .hex)")
//expected-error@-1 {{no exact matches in call to instance method 'appendInterpolation'}}
_osLogTestHelper("\(10, format: .myFormat, privacy: .private)")
//expected-error@-1 {{type 'OSLogIntegerFormatting' has no member 'myFormat'}}
}
// Test diagnostics in extensions to OSLogInterpolation. This is not officially
// supported yet.
struct MyStruct {
var i: Int
}
extension OSLogInterpolation {
mutating func appendInterpolation(a: MyStruct) {
self.appendInterpolation(a.i)
}
mutating func appendInterpolation(a: MyStruct, format: OSLogIntegerFormatting) {
self.appendInterpolation(a.i, format: format)
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
@_semantics("oslog.requires_constant_arguments")
mutating func appendInterpolation(a: MyStruct, constFormat: OSLogIntegerFormatting) {
self.appendInterpolation(a.i, format: constFormat)
}
}
func testOSLogInterpolationExtension(a: MyStruct) {
// The following is not a Sema error but would result in SIL diagnostics as
// the appendInterpolation overload is not marked as constant_evaluable.
_osLogTestHelper("Error at line: \(a: a)")
}
func testExplicitOSLogMessageConstruction() {
_osLogTestHelper(OSLogMessage(stringLiteral: "world"))
// expected-error@-1 {{argument must be a string interpolation}}
_osLogTestHelper(
OSLogMessage( // expected-error {{argument must be a string interpolation}}
stringInterpolation:
OSLogInterpolation(
literalCapacity: 0,
interpolationCount: 0)))
}
// Test that @_semantics("oslog.log_with_level") permits values of type OSLog and
// OSLogType to not be constants.
class OSLog { }
class OSLogType { }
@_semantics("oslog.log_with_level")
func osLogWithLevel(_ level: OSLogType, log: OSLog, _ message: OSLogMessage) {
}
func testNonConstantLogObjectLevel(
level: OSLogType,
log: OSLog,
message: OSLogMessage
) {
osLogWithLevel(level, log: log, "message with no payload")
var levelOpt: OSLogType? = nil
levelOpt = level
let logClosure = { log }
osLogWithLevel(levelOpt!, log: logClosure(), "A string \("hello")")
osLogWithLevel(level, log: log, message)
// expected-error@-1 {{argument must be a string interpolation}}
}
// Test that log messages can be wrapped in constant_evaluable functions.
// A function similar to the one used by SwiftUI preview to wrap string
// literals.
@_semantics("constant_evaluable")
public func __designTimeStringStub(
_ key: String,
fallback: OSLogMessage
) -> OSLogMessage {
fallback
}
func testSwiftUIPreviewWrapping() {
// This should not produce any diagnostics.
_osLogTestHelper(__designTimeStringStub("key", fallback: "A literal message"))
}
public func nonConstantFunction(
_ key: String,
fallback: OSLogMessage
) -> OSLogMessage {
fallback
}
func testLogMessageWrappingDiagnostics() {
_osLogTestHelper(nonConstantFunction("key", fallback: "A literal message"))
// expected-error@-1{{argument must be a string interpolation}}
}
// Test closure expressions
func funcAcceptingClosure<T>(_ x: () -> T) -> T {
return x()
}
func normalFunction() {}
func testCallsWithinClosures(formatOpt: OSLogIntegerFormatting) {
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
_osLogTestHelper("Maximum integer value: \(Int.max, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
funcAcceptingClosure {
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
}
funcAcceptingClosure {
normalFunction()
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
}
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: .hex)")
}
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: .hex)")
_osLogTestHelper("Maximum integer value: \(Int.max, privacy: .public)")
}
}