@@ -24,13 +24,6 @@ open FSharp.Compiler.TypeProviders
24
24
open FSharp.Core .CompilerServices
25
25
#endif
26
26
27
- exception ObsoleteDiagnostic of
28
- isError: bool *
29
- diagnosticId: string *
30
- message: string *
31
- urlFormat: string *
32
- range: range
33
-
34
27
let fail () = failwith " This custom attribute has an argument that cannot yet be converted using this API"
35
28
36
29
let rec private evalILAttribElem elem =
@@ -247,44 +240,68 @@ let private CheckCompilerFeatureRequiredAttribute (g: TcGlobals) cattrs msg m =
247
240
| Some([ ILAttribElem.String ( Some featureName) ], _) when featureName = " RequiredMembers" ->
248
241
CompleteD
249
242
| _ ->
250
- ErrorD ( ObsoleteDiagnostic( true , " " , msg, " " , m))
243
+ ErrorD ( ObsoleteDiagnostic( true , None, msg, None, m))
244
+
245
+ let private extractILAttribValueFrom name namedArgs =
246
+ match namedArgs with
247
+ | ExtractILAttributeNamedArg name ( AttribElemStringArg v) -> Some v
248
+ | _ -> None
251
249
252
- let private extractILObsoleteAttributeInfo namedArgs =
253
- let extractILAttribValueFrom name namedArgs =
254
- match namedArgs with
255
- | ExtractILAttributeNamedArg name ( AttribElemStringArg v) -> v
256
- | _ -> " "
250
+ let private extractILAttributeInfo namedArgs =
257
251
let diagnosticId = extractILAttribValueFrom " DiagnosticId" namedArgs
258
252
let urlFormat = extractILAttribValueFrom " UrlFormat" namedArgs
259
253
( diagnosticId, urlFormat)
260
254
255
+ let private CheckILExperimentalAttributes ( g : TcGlobals ) cattrs m =
256
+ let ( AttribInfo ( tref , _ )) = g.attrib_ IlExperimentalAttribute
257
+ match TryDecodeILAttribute tref cattrs with
258
+ // [Experimental("DiagnosticId")]
259
+ // [Experimental(diagnosticId: "DiagnosticId")]
260
+ // [Experimental("DiagnosticId", UrlFormat = "UrlFormat")]
261
+ // [Experimental(diagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")]
262
+ // Constructors deciding on DiagnosticId and UrlFormat properties.
263
+ | Some ([ attribElement ], namedArgs) ->
264
+ let diagnosticId =
265
+ match attribElement with
266
+ | ILAttribElem.String ( Some msg) -> Some msg
267
+ | ILAttribElem.String None
268
+ | _ -> None
269
+
270
+ let message = extractILAttribValueFrom " Message" namedArgs
271
+ let urlFormat = extractILAttribValueFrom " UrlFormat" namedArgs
272
+
273
+ WarnD( Experimental( message, diagnosticId, urlFormat, m))
274
+ // Empty constructor or only UrlFormat property are not allowed.
275
+ | Some _
276
+ | None -> CompleteD
277
+
261
278
let private CheckILObsoleteAttributes ( g : TcGlobals ) isByrefLikeTyconRef cattrs m =
262
279
if isByrefLikeTyconRef then
263
280
CompleteD
264
281
else
265
282
let ( AttribInfo ( tref , _ )) = g.attrib_ SystemObsolete
266
283
match TryDecodeILAttribute tref cattrs with
267
- // [< Obsolete> ]
268
- // [< Obsolete("Message")> ]
269
- // [< Obsolete("Message", true)> ]
270
- // [< Obsolete("Message", DiagnosticId = "DiagnosticId")> ]
271
- // [< Obsolete("Message", DiagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")> ]
272
- // [< Obsolete(DiagnosticId = "DiagnosticId")> ]
273
- // [< Obsolete(DiagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")> ]
274
- // [< Obsolete("Message", true, DiagnosticId = "DiagnosticId")> ]
275
- // [< Obsolete("Message", true, DiagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")> ]
284
+ // [Obsolete]
285
+ // [Obsolete("Message")]
286
+ // [Obsolete("Message", true)]
287
+ // [Obsolete("Message", DiagnosticId = "DiagnosticId")]
288
+ // [Obsolete("Message", DiagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")]
289
+ // [Obsolete(DiagnosticId = "DiagnosticId")]
290
+ // [Obsolete(DiagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")]
291
+ // [Obsolete("Message", true, DiagnosticId = "DiagnosticId")]
292
+ // [Obsolete("Message", true, DiagnosticId = "DiagnosticId", UrlFormat = "UrlFormat")]
276
293
// Constructors deciding on IsError and Message properties.
277
294
| Some ([ attribElement ], namedArgs) ->
278
- let diagnosticId , urlFormat = extractILObsoleteAttributeInfo namedArgs
295
+ let diagnosticId , urlFormat = extractILAttributeInfo namedArgs
279
296
let msg =
280
297
match attribElement with
281
- | ILAttribElem.String ( Some msg) -> msg
298
+ | ILAttribElem.String ( Some msg) -> Some msg
282
299
| ILAttribElem.String None
283
- | _ -> " "
300
+ | _ -> None
284
301
285
302
WarnD ( ObsoleteDiagnostic( false , diagnosticId, msg, urlFormat, m))
286
- | Some ([ ILAttribElem.String ( Some msg) ; ILAttribElem.Bool isError ], namedArgs) ->
287
- let diagnosticId , urlFormat = extractILObsoleteAttributeInfo namedArgs
303
+ | Some ([ ILAttribElem.String msg; ILAttribElem.Bool isError ], namedArgs) ->
304
+ let diagnosticId , urlFormat = extractILAttributeInfo namedArgs
288
305
if isError then
289
306
if g.langVersion.SupportsFeature( LanguageFeature.RequiredPropertiesSupport) then
290
307
CheckCompilerFeatureRequiredAttribute g cattrs msg m
@@ -294,24 +311,23 @@ let private CheckILObsoleteAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs
294
311
WarnD ( ObsoleteDiagnostic( false , diagnosticId, msg, urlFormat, m))
295
312
// Only DiagnosticId, UrlFormat
296
313
| Some (_, namedArgs) ->
297
- let diagnosticId , urlFormat = extractILObsoleteAttributeInfo namedArgs
298
- WarnD( ObsoleteDiagnostic( false , diagnosticId, " " , urlFormat, m))
314
+ let diagnosticId , urlFormat = extractILAttributeInfo namedArgs
315
+ WarnD( ObsoleteDiagnostic( false , diagnosticId, None , urlFormat, m))
299
316
// No arguments
300
317
| None -> CompleteD
301
318
302
- /// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data
319
+ /// Check IL attributes for Experimental, warnings as data
303
320
let private CheckILAttributes ( g : TcGlobals ) isByrefLikeTyconRef cattrs m =
304
321
trackErrors {
305
322
do ! CheckILObsoleteAttributes g isByrefLikeTyconRef cattrs m
323
+ do ! CheckILExperimentalAttributes g cattrs m
306
324
}
307
325
308
- let langVersionPrefix = " --langversion:preview"
309
-
310
326
let private extractObsoleteAttributeInfo namedArgs =
311
327
let extractILAttribValueFrom name namedArgs =
312
328
match namedArgs with
313
- | ExtractAttribNamedArg name ( AttribStringArg v) -> v
314
- | _ -> " "
329
+ | ExtractAttribNamedArg name ( AttribStringArg v) -> Some v
330
+ | _ -> None
315
331
let diagnosticId = extractILAttribValueFrom " DiagnosticId" namedArgs
316
332
let urlFormat = extractILAttribValueFrom " UrlFormat" namedArgs
317
333
( diagnosticId, urlFormat)
@@ -331,17 +347,17 @@ let private CheckObsoleteAttributes g attribs m =
331
347
// Constructors deciding on IsError and Message properties.
332
348
| Some( Attrib( unnamedArgs= [ AttribStringArg s ]; propVal= namedArgs)) ->
333
349
let diagnosticId , urlFormat = extractObsoleteAttributeInfo namedArgs
334
- do ! WarnD( ObsoleteDiagnostic( false , diagnosticId, s, urlFormat, m))
350
+ do ! WarnD( ObsoleteDiagnostic( false , diagnosticId, Some s, urlFormat, m))
335
351
| Some( Attrib( unnamedArgs= [ AttribStringArg s; AttribBoolArg( isError) ]; propVal= namedArgs)) ->
336
352
let diagnosticId , urlFormat = extractObsoleteAttributeInfo namedArgs
337
353
if isError then
338
- do ! ErrorD ( ObsoleteDiagnostic( true , diagnosticId, s, urlFormat, m))
354
+ do ! ErrorD ( ObsoleteDiagnostic( true , diagnosticId, Some s, urlFormat, m))
339
355
else
340
- do ! WarnD ( ObsoleteDiagnostic( false , diagnosticId, s, urlFormat, m))
356
+ do ! WarnD ( ObsoleteDiagnostic( false , diagnosticId, Some s, urlFormat, m))
341
357
// Only DiagnosticId, UrlFormat
342
358
| Some( Attrib( propVal= namedArgs)) ->
343
359
let diagnosticId , urlFormat = extractObsoleteAttributeInfo namedArgs
344
- do ! WarnD( ObsoleteDiagnostic( false , diagnosticId, " " , urlFormat, m))
360
+ do ! WarnD( ObsoleteDiagnostic( false , diagnosticId, None , urlFormat, m))
345
361
| None -> ()
346
362
}
347
363
@@ -366,21 +382,21 @@ let private CheckCompilerMessageAttribute g attribs m =
366
382
()
367
383
}
368
384
369
- let private CheckExperimentalAttribute g attribs m =
385
+ let private CheckFSharpExperimentalAttribute g attribs m =
370
386
trackErrors {
371
387
match TryFindFSharpAttribute g g.attrib_ ExperimentalAttribute attribs with
388
+ // [<Experimental("Message")>]
372
389
| Some( Attrib( unnamedArgs= [ AttribStringArg( s) ])) ->
373
390
let isExperimentalAttributeDisabled ( s : string ) =
374
391
if g.compilingFSharpCore then
375
392
true
376
393
else
377
- g.langVersion.IsPreviewEnabled && ( s.IndexOf( langVersionPrefix , StringComparison.OrdinalIgnoreCase) >= 0 )
394
+ g.langVersion.IsPreviewEnabled && ( s.IndexOf( " --langversion:preview " , StringComparison.OrdinalIgnoreCase) >= 0 )
378
395
if not ( isExperimentalAttributeDisabled s) then
379
- do ! WarnD( Experimental( s, m))
380
- | Some _ ->
381
- do ! WarnD( Experimental( FSComp.SR.experimentalConstruct (), m))
382
- | _ ->
383
- ()
396
+ do ! WarnD( Experimental( Some s, None, None, m))
397
+ // Empty constructor is not allowed.
398
+ | Some _
399
+ | _ -> ()
384
400
}
385
401
386
402
let private CheckUnverifiableAttribute g attribs m =
@@ -399,7 +415,7 @@ let CheckFSharpAttributes (g:TcGlobals) attribs m =
399
415
trackErrors {
400
416
do ! CheckObsoleteAttributes g attribs m
401
417
do ! CheckCompilerMessageAttribute g attribs m
402
- do ! CheckExperimentalAttribute g attribs m
418
+ do ! CheckFSharpExperimentalAttribute g attribs m
403
419
do ! CheckUnverifiableAttribute g attribs m
404
420
}
405
421
@@ -408,16 +424,16 @@ let CheckFSharpAttributes (g:TcGlobals) attribs m =
408
424
let private CheckProvidedAttributes ( g : TcGlobals ) m ( provAttribs : Tainted < IProvidedCustomAttributeProvider >) =
409
425
let ( AttribInfo ( tref , _ )) = g.attrib_ SystemObsolete
410
426
match provAttribs.PUntaint(( fun a -> a.GetAttributeConstructorArgs( provAttribs.TypeProvider.PUntaintNoFailure( id), tref.FullName)), m) with
411
- | Some ([ Some (:? string as msg) ], _) -> WarnD( ObsoleteDiagnostic( false , " " , msg, " " , m))
427
+ | Some ([ Some (:? string as msg) ], _) -> WarnD( ObsoleteDiagnostic( false , None , Some msg, None , m))
412
428
| Some ([ Some (:? string as msg); Some (:? bool as isError) ], _) ->
413
429
if isError then
414
- ErrorD ( ObsoleteDiagnostic( true , " " , msg, " " , m))
430
+ ErrorD ( ObsoleteDiagnostic( true , None , Some msg, None , m))
415
431
else
416
- WarnD ( ObsoleteDiagnostic( false , " " , msg, " " , m))
432
+ WarnD ( ObsoleteDiagnostic( false , None , Some msg, None , m))
417
433
| Some ([ None ], _) ->
418
- WarnD( ObsoleteDiagnostic( false , " " , " " , " " , m))
434
+ WarnD( ObsoleteDiagnostic( false , None , None , None , m))
419
435
| Some _ ->
420
- WarnD( ObsoleteDiagnostic( false , " " , " " , " " , m))
436
+ WarnD( ObsoleteDiagnostic( false , None , None , None , m))
421
437
| None ->
422
438
CompleteD
423
439
#endif
0 commit comments