@@ -21,6 +21,7 @@ import SwiftIfConfig
21
21
extension ASTGenVisitor {
22
22
/// Implementation detail for `generateAvailableAttr(attribute:)` and `generateSpecializeAttr(attribute:)`.
23
23
func generateAvailableAttr(
24
+ attribute attrNode: AttributeSyntax ,
24
25
atLoc: BridgedSourceLoc ,
25
26
range: BridgedSourceRange ,
26
27
attrName: SyntaxText ,
@@ -43,14 +44,15 @@ extension ASTGenVisitor {
43
44
isShorthand = false
44
45
}
45
46
if isShorthand {
46
- return self . generateAvailableAttrShorthand ( atLoc: atLoc, range: range, args: args, isSPI: isSPI)
47
+ return self . generateAvailableAttrShorthand ( attribute : attrNode , atLoc: atLoc, range: range, args: args, isSPI: isSPI)
47
48
}
48
49
}
49
50
50
51
// E.g.
51
52
// @available(macOS, introduced: 10.12, deprecated: 11.2)
52
53
// @available(*, unavailable, message: "out of service")
53
- let attr = self . generateAvailableAttrExtended ( atLoc: atLoc, range: range, args: args, isSPI: isSPI)
54
+ let attr = self . generateAvailableAttrExtended ( attribute: attrNode, atLoc: atLoc, range: range, args: args, isSPI: isSPI)
55
+
54
56
if let attr {
55
57
return [ attr]
56
58
} else {
@@ -66,6 +68,7 @@ extension ASTGenVisitor {
66
68
}
67
69
68
70
func generateAvailableAttrShorthand(
71
+ attribute attrNode: AttributeSyntax ,
69
72
atLoc: BridgedSourceLoc ,
70
73
range: BridgedSourceRange ,
71
74
args: AvailabilityArgumentListSyntax ,
@@ -121,6 +124,7 @@ extension ASTGenVisitor {
121
124
}
122
125
123
126
func generateAvailableAttrExtended(
127
+ attribute attrNode: AttributeSyntax ,
124
128
atLoc: BridgedSourceLoc ,
125
129
range: BridgedSourceRange ,
126
130
args: AvailabilityArgumentListSyntax ,
@@ -165,16 +169,17 @@ extension ASTGenVisitor {
165
169
var renamed : BridgedStringRef ? = nil
166
170
167
171
func generateVersion( arg: AvailabilityLabeledArgumentSyntax , into target: inout VersionAndRange ? ) {
168
- guard let versionSytnax = arg. value. as ( VersionTupleSyntax . self) else {
169
- // TODO: Diagnose
170
- fatalError ( " expected version after introduced, deprecated, or obsoleted " )
171
- }
172
- guard let version = VersionTuple ( parsing: versionSytnax. trimmedDescription) else {
173
- // TODO: Diagnose
174
- fatalError ( " invalid version string " )
175
- }
176
172
if target != nil {
177
- // TODO: Diagnose duplicated.
173
+ diagnose ( . duplicatedLabeledArgumentInAttribute( attrNode, argument: arg, name: arg. label. text) )
174
+ return
175
+ }
176
+ guard
177
+ let versionSytnax = arg. value. as ( VersionTupleSyntax . self) ,
178
+ let version = VersionTuple ( parsing: versionSytnax. trimmedDescription)
179
+ else {
180
+ // FIXME: This is already diagnosed in ParserDiagnostics.
181
+ // diagnose(.expectedVersionNumberInAvailableAttr(arg))
182
+ return
178
183
}
179
184
180
185
target = . init( version: version, range: self . generateSourceRange ( versionSytnax) )
@@ -195,7 +200,7 @@ extension ASTGenVisitor {
195
200
case " noasync " :
196
201
attrKind = . noAsync
197
202
default :
198
- // TODO: Diagnose
203
+ diagnose ( . unexpectedArgumentInAttribute ( attrNode , arg ) )
199
204
continue
200
205
}
201
206
@@ -224,31 +229,35 @@ extension ASTGenVisitor {
224
229
generateVersion ( arg: arg, into: & obsoleted)
225
230
case . message:
226
231
guard let literal = arg. value. as ( SimpleStringLiteralExprSyntax . self) else {
227
- // TODO: Diagnose.
228
- fatalError ( " invalid argument type for 'message:' " )
232
+ diagnose ( . expectedArgumentValueInAttribute ( attrNode , label : " message " , value : " string literal " , at : arg . value ) )
233
+ continue
229
234
}
230
235
guard let _message = self . generateStringLiteralTextIfNotInterpolated ( expr: literal) else {
231
- fatalError ( " invalid literal value " )
236
+ diagnose ( . stringInterpolationNotAllowedInAttribute( attrNode, at: literal) )
237
+ continue
232
238
}
233
239
guard message == nil else {
234
- fatalError ( " duplicated 'message' argument " )
240
+ diagnose ( . duplicatedLabeledArgumentInAttribute( attrNode, argument: arg, name: " message " ) )
241
+ continue
235
242
}
236
243
message = _message
237
244
case . renamed:
238
245
guard let literal = arg. value. as ( SimpleStringLiteralExprSyntax . self) else {
239
- // TODO: Diagnose.
240
- fatalError ( " invalid argument type for 'renamed:' " )
246
+ diagnose ( . expectedArgumentValueInAttribute ( attrNode , label : " renamed " , value : " string literal " , at : arg . value ) )
247
+ continue
241
248
}
242
249
guard let _renamed = self . generateStringLiteralTextIfNotInterpolated ( expr: literal) else {
243
- fatalError ( " invalid literal value " )
250
+ diagnose ( . stringInterpolationNotAllowedInAttribute( attrNode, at: literal) )
251
+ continue
244
252
}
245
253
guard renamed == nil else {
246
- fatalError ( " duplicated 'message' argument " )
254
+ diagnose ( . duplicatedLabeledArgumentInAttribute( attrNode, argument: arg, name: " renamed " ) )
255
+ continue
247
256
}
248
257
renamed = _renamed
249
258
case . invalid:
250
- // TODO: Diagnose
251
- fatalError ( " invalid labeled argument " )
259
+ diagnose ( . unexpectedArgumentInAttribute ( attrNode , arg ) )
260
+ continue
252
261
}
253
262
}
254
263
}
@@ -333,8 +342,8 @@ extension ASTGenVisitor {
333
342
// Was not a macro, it should be a valid platform name.
334
343
let platform = self . generateIdentifierAndSourceLoc ( domainNode)
335
344
guard let version = version else {
336
- // TODO: Diagnostics.
337
- fatalError ( " expected version " )
345
+ diagnose ( . expectedVersionNumberAfterPlatform ( domainNode ) )
346
+ return
338
347
}
339
348
// FIXME: Wasting ASTContext memory.
340
349
// 'AvailabilitySpec' is 'ASTAllocated' but created spec is ephemeral in context of `@available` attributes.
@@ -361,8 +370,9 @@ extension ASTGenVisitor {
361
370
case . availabilityVersionRestriction( let platformVersion) :
362
371
handle ( domainNode: platformVersion. platform, versionNode: platformVersion. version)
363
372
default :
364
- // TODO: Diagnostics.
365
- fatalError ( " invalid argument kind for availability spec " )
373
+ // FIXME: This is unreachable? ParserDiagnostics emits 'expected platform name'.
374
+ let token = parsed. argument. firstToken ( viewMode: . sourceAccurate) !
375
+ diagnose ( . unexpectedArgumentInAvailabilitySpecList( token) )
366
376
}
367
377
}
368
378
0 commit comments