14
14
using System . Threading ;
15
15
using P = Hl7 . Fhir . ElementModel . Types ;
16
16
17
+ #nullable enable
18
+
17
19
namespace Hl7 . Fhir . ElementModel
18
20
{
19
21
internal class TypedElementOnSourceNode : ITypedElement , IAnnotated , IExceptionSource , IShortPathGenerator
20
22
{
21
23
private const string XHTML_INSTANCETYPE = "xhtml" ;
22
24
private const string XHTML_DIV_TAG_NAME = "div" ;
23
25
24
- public TypedElementOnSourceNode ( ISourceNode source , string type , IStructureDefinitionSummaryProvider provider , TypedElementSettings settings = null )
26
+ public TypedElementOnSourceNode ( ISourceNode source , string ? type , IStructureDefinitionSummaryProvider provider , TypedElementSettings ? settings = null )
25
27
{
26
28
if ( source == null ) throw Error . ArgumentNull ( nameof ( source ) ) ;
27
29
@@ -31,12 +33,13 @@ public TypedElementOnSourceNode(ISourceNode source, string type, IStructureDefin
31
33
if ( source is IExceptionSource ies && ies . ExceptionHandler == null )
32
34
ies . ExceptionHandler = ( o , a ) => ExceptionHandler . NotifyOrThrow ( o , a ) ;
33
35
36
+ Location = source . Name ;
34
37
ShortPath = source . Name ;
35
38
_source = source ;
36
39
( InstanceType , Definition ) = buildRootPosition ( type ) ;
37
40
}
38
41
39
- private ( string instanceType , IElementDefinitionSummary definition ) buildRootPosition ( string type )
42
+ private ( string instanceType , IElementDefinitionSummary ? definition ) buildRootPosition ( string ? type )
40
43
{
41
44
var rootType = type ?? _source . GetResourceTypeIndicator ( ) ;
42
45
if ( rootType == null )
@@ -45,7 +48,7 @@ public TypedElementOnSourceNode(ISourceNode source, string type, IStructureDefin
45
48
throw Error . Format ( nameof ( type ) , $ "Cannot determine the type of the root element at '{ _source . Location } ', " +
46
49
$ "please supply a type argument.") ;
47
50
else
48
- return ( rootType , null ) ;
51
+ return ( "Base" , null ) ;
49
52
}
50
53
51
54
var elementType = Provider . Provide ( rootType ) ;
@@ -66,7 +69,7 @@ public TypedElementOnSourceNode(ISourceNode source, string type, IStructureDefin
66
69
}
67
70
68
71
69
- private TypedElementOnSourceNode ( TypedElementOnSourceNode parent , ISourceNode source , IElementDefinitionSummary definition , string instanceType , string prettyPath )
72
+ private TypedElementOnSourceNode ( TypedElementOnSourceNode parent , ISourceNode source , IElementDefinitionSummary ? definition , string instanceType , string prettyPath , string location )
70
73
{
71
74
_source = source ;
72
75
ShortPath = prettyPath ;
@@ -75,11 +78,12 @@ private TypedElementOnSourceNode(TypedElementOnSourceNode parent, ISourceNode so
75
78
Definition = definition ;
76
79
InstanceType = instanceType ;
77
80
_settings = parent . _settings ;
81
+ Location = location ;
78
82
}
79
83
80
- public ExceptionNotificationHandler ExceptionHandler { get ; set ; }
84
+ public ExceptionNotificationHandler ? ExceptionHandler { get ; set ; }
81
85
82
- private void raiseTypeError ( string message , object source , bool warning = false , string location = null )
86
+ private void raiseTypeError ( string message , object source , bool warning = false , string ? location = null )
83
87
{
84
88
var exMessage = $ "Type checking the data: { message } ";
85
89
if ( ! string . IsNullOrEmpty ( location ) )
@@ -101,7 +105,7 @@ private void raiseTypeError(string message, object source, bool warning = false,
101
105
102
106
private readonly TypedElementSettings _settings ;
103
107
104
- public IElementDefinitionSummary Definition { get ; private set ; }
108
+ public IElementDefinitionSummary ? Definition { get ; private set ; }
105
109
106
110
public string Name => Definition ? . ElementName ?? _source . Name ;
107
111
@@ -120,7 +124,7 @@ private void raiseTypeError(string message, object source, bool warning = false,
120
124
// R3 and R4, these value (and url and id elements by the way) will indicate which type
121
125
// of system types there are, implicitly specifying the mapping between primitive
122
126
// FHIR types and system types.
123
- private static Type tryMapFhirPrimitiveTypeToSystemType ( string fhirType )
127
+ private static Type ? tryMapFhirPrimitiveTypeToSystemType ( string fhirType )
124
128
{
125
129
switch ( fhirType )
126
130
{
@@ -158,7 +162,7 @@ private static Type tryMapFhirPrimitiveTypeToSystemType(string fhirType)
158
162
}
159
163
}
160
164
161
- private object valueFactory ( )
165
+ private object ? valueFactory ( )
162
166
{
163
167
string sourceText = _source . Text ;
164
168
@@ -209,7 +213,7 @@ private object valueFactory()
209
213
if ( P . Any . TryParse ( sourceText , typeof ( P . DateTime ) , out var dateTimeVal ) )
210
214
{
211
215
// TruncateToDate converts 1991-02-03T11:22:33Z to 1991-02-03+00:00 which is not a valid date!
212
- var date = ( dateTimeVal as P . DateTime ) . TruncateToDate ( ) ;
216
+ var date = ( dateTimeVal as P . DateTime ) ! . TruncateToDate ( ) ;
213
217
// so we cut off timezone by converting it to timeoffset and cast back to date.
214
218
return P . Date . FromDateTimeOffset ( date . ToDateTimeOffset ( 0 , 0 , 0 , TimeSpan . Zero ) ) ;
215
219
}
@@ -220,13 +224,13 @@ private object valueFactory()
220
224
}
221
225
}
222
226
223
- private object _value ;
227
+ private object ? _value ;
224
228
private bool _valueInitialized = false ;
225
229
private static object _initializationLock = new ( ) ;
226
230
227
- public object Value => LazyInitializer . EnsureInitialized ( ref _value , ref _valueInitialized , ref _initializationLock , valueFactory ) ;
231
+ public object Value => LazyInitializer . EnsureInitialized ( ref _value , ref _valueInitialized , ref _initializationLock , valueFactory ) ! ;
228
232
229
- private string deriveInstanceType ( ISourceNode current , IElementDefinitionSummary info )
233
+ private string ? deriveInstanceType ( ISourceNode current , IElementDefinitionSummary info )
230
234
{
231
235
var resourceTypeIndicator = current . GetResourceTypeIndicator ( ) ;
232
236
@@ -338,7 +342,7 @@ private string typeFromLogicalModelCanonical(ITypeSerializationInfo info)
338
342
return pos > - 1 ? type . Substring ( pos + 1 ) : type ;
339
343
}
340
344
341
- private bool tryGetBySuffixedName ( Dictionary < string , IElementDefinitionSummary > dis , string name , out IElementDefinitionSummary info )
345
+ private bool tryGetBySuffixedName ( Dictionary < string , IElementDefinitionSummary > dis , string name , out IElementDefinitionSummary ? info )
342
346
{
343
347
// Simplest case, one on one match between name and element name
344
348
if ( dis . TryGetValue ( name , out info ) )
@@ -361,7 +365,7 @@ private bool tryGetBySuffixedName(Dictionary<string, IElementDefinitionSummary>
361
365
}
362
366
}
363
367
364
- private IEnumerable < TypedElementOnSourceNode > enumerateElements ( Dictionary < string , IElementDefinitionSummary > dis , ISourceNode parent , string name )
368
+ private IEnumerable < TypedElementOnSourceNode > enumerateElements ( Dictionary < string , IElementDefinitionSummary > dis , ISourceNode parent , string ? name )
365
369
{
366
370
IEnumerable < ISourceNode > childSet ;
367
371
@@ -372,17 +376,17 @@ private IEnumerable<TypedElementOnSourceNode> enumerateElements(Dictionary<strin
372
376
{
373
377
var hit = dis . TryGetValue ( name , out var info ) ;
374
378
childSet = hit
375
- ? ( info . IsChoiceElement ? parent . Children ( name + "*" ) : parent . Children ( name ) )
379
+ ? ( info ! . IsChoiceElement ? parent . Children ( name + "*" ) : parent . Children ( name ) )
376
380
: Enumerable . Empty < ISourceNode > ( ) ;
377
381
}
378
382
379
- string lastName = null ;
383
+ string ? lastName = null ;
380
384
int _nameIndex = 0 ;
381
385
382
386
foreach ( var scan in childSet )
383
387
{
384
388
var hit = tryGetBySuffixedName ( dis , scan . Name , out var info ) ;
385
- string instanceType = info == null ? null :
389
+ string ? instanceType = info == null ? null :
386
390
deriveInstanceType ( scan , info ) ;
387
391
388
392
// If we have definitions for the children, but we didn't find definitions for this
@@ -406,28 +410,31 @@ private IEnumerable<TypedElementOnSourceNode> enumerateElements(Dictionary<strin
406
410
}
407
411
408
412
var prettyPath =
409
- hit && ! info . IsCollection ? $ "{ ShortPath } .{ info . ElementName } " : $ "{ ShortPath } .{ scan . Name } [{ _nameIndex } ]";
413
+ hit && ! info ! . IsCollection ? $ "{ ShortPath } .{ info . ElementName } " : $ "{ ShortPath } .{ scan . Name } [{ _nameIndex } ]";
414
+
415
+ var location =
416
+ hit ? $ "{ Location } .{ info ! . ElementName } [{ _nameIndex } ]" : $ "{ Location } .{ scan . Name } [{ _nameIndex } ]";
410
417
411
418
// Special condition for ccda.
412
419
// If we encounter a xhtml node in a ccda document we will flatten all childnodes
413
420
// and use their content to build up the xml.
414
421
// The xml will be put in this node and children will be ignored.
415
- if ( instanceType == XHTML_INSTANCETYPE && info . Representation == XmlRepresentation . CdaText )
422
+ if ( instanceType == XHTML_INSTANCETYPE && info ! . Representation == XmlRepresentation . CdaText )
416
423
{
417
424
#pragma warning disable CS0618 // Type or member is obsolete
418
425
var xmls = scan . Children ( ) . Select ( c => c . Annotation < ICdaInfoSupplier > ( ) ? . XHtmlText ) ;
419
426
#pragma warning restore CS0618 // Type or member is obsolete
420
427
421
428
var source = SourceNode . Valued ( scan . Name , string . Join ( string . Empty , xmls ) ) ;
422
- yield return new TypedElementOnSourceNode ( this , source , info , instanceType , prettyPath ) ;
429
+ yield return new TypedElementOnSourceNode ( this , source , info , instanceType , prettyPath , location ) ;
423
430
continue ;
424
431
}
425
432
426
- yield return new TypedElementOnSourceNode ( this , scan , info , instanceType , prettyPath ) ;
433
+ yield return new TypedElementOnSourceNode ( this , scan , info , instanceType ! , prettyPath , location ) ;
427
434
}
428
435
}
429
436
430
- public IEnumerable < ITypedElement > Children ( string name = null )
437
+ public IEnumerable < ITypedElement > Children ( string ? name = null )
431
438
{
432
439
// If we have an xhtml typed node and there is not a div tag around the content
433
440
// then we will not enumerate through the children of this node, since there will be no types
@@ -461,13 +468,13 @@ public IEnumerable<ITypedElement> Children(string name = null)
461
468
private IEnumerable < ITypedElement > runAdditionalRules ( IEnumerable < ITypedElement > children )
462
469
{
463
470
#pragma warning disable 612 , 618
464
- var additionalRules = _source . Annotations ( typeof ( AdditionalStructuralRule ) ) ;
471
+ var additionalRules = _source . Annotations < AdditionalStructuralRule > ( ) . ToArray ( ) ;
465
472
var stateBag = new Dictionary < AdditionalStructuralRule , object > ( ) ;
466
473
foreach ( var child in children )
467
474
{
468
- foreach ( var rule in additionalRules . Cast < AdditionalStructuralRule > ( ) )
475
+ foreach ( var rule in additionalRules )
469
476
{
470
- stateBag . TryGetValue ( rule , out object state ) ;
477
+ stateBag . TryGetValue ( rule , out object ? state ) ;
471
478
state = rule ( child , this , state ) ;
472
479
if ( state != null ) stateBag [ rule ] = state ;
473
480
}
@@ -477,25 +484,23 @@ private IEnumerable<ITypedElement> runAdditionalRules(IEnumerable<ITypedElement>
477
484
#pragma warning restore 612 , 618
478
485
}
479
486
480
- public string Location => _source . Location ;
487
+ public string Location { get ; init ; }
481
488
482
489
public string ShortPath { get ; private set ; }
483
490
484
491
public override string ToString ( ) =>
485
- $ "{ ( InstanceType != null ? ( $ "[{ InstanceType } ] ") : "" ) } { _source } ";
492
+ $ "{ ( ( $ "[{ InstanceType } ] ") ) } { _source } ";
486
493
487
494
public IEnumerable < object > Annotations ( Type type )
488
495
{
489
- #pragma warning disable IDE0046 // Convert to conditional expression
490
496
if ( type == typeof ( TypedElementOnSourceNode ) || type == typeof ( ITypedElement ) || type == typeof ( IShortPathGenerator ) )
491
- #pragma warning restore IDE0046 // Convert to conditional expression
492
497
return new [ ] { this } ;
493
498
else
494
499
return _source . Annotations ( type ) ;
495
500
}
496
501
}
497
502
498
503
[ Obsolete ( "This class is used for internal purposes and is subject to change without notice. Don't use." ) ]
499
- public delegate object AdditionalStructuralRule ( ITypedElement node , IExceptionSource ies , object state ) ;
504
+ public delegate object ? AdditionalStructuralRule ( ITypedElement node , IExceptionSource ies , object ? state ) ;
500
505
}
501
506
0 commit comments