diff --git a/src/Hl7.Fhir.Base/CompatibilitySuppressions.xml b/src/Hl7.Fhir.Base/CompatibilitySuppressions.xml
index beb25c62eb..2fa777b8c6 100644
--- a/src/Hl7.Fhir.Base/CompatibilitySuppressions.xml
+++ b/src/Hl7.Fhir.Base/CompatibilitySuppressions.xml
@@ -36,6 +36,20 @@
lib/net8.0/Hl7.Fhir.Base.dll
true
+
+ CP0002
+ F:Hl7.FhirPath.Functions.EqualityOperators.TypedElementEqualityComparer
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.ElementModel.ElementNodeExtensions.ToScopedNode(Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
CP0002
M:Hl7.Fhir.ElementModel.ScopedNode.Children(System.String)
@@ -106,6 +120,62 @@
lib/net8.0/Hl7.Fhir.Base.dll
true
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.ElementNavFhirExtensions.HasValue(Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.ElementNavFhirExtensions.HtmlChecks(Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.ElementNavFhirExtensions.ToFhirValues(System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement})
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.FhirEvaluationContext.#ctor(Hl7.Fhir.ElementModel.ITypedElement,Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.FhirEvaluationContext.#ctor(Hl7.Fhir.ElementModel.ITypedElement,System.Collections.Generic.IDictionary{System.String,System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement}})
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.FhirEvaluationContext.#ctor(Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.FhirEvaluationContext.#ctor(Hl7.Fhir.ElementModel.ScopedNode)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.Fhir.FhirPath.FhirEvaluationContext.CreateDefault
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
CP0002
M:Hl7.Fhir.FhirPath.FhirEvaluationContext.get_ElementResolver
@@ -260,6 +330,104 @@
lib/net8.0/Hl7.Fhir.Base.dll
true
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpression.BeginInvoke(Hl7.Fhir.ElementModel.ITypedElement,Hl7.FhirPath.EvaluationContext,System.AsyncCallback,System.Object)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpression.EndInvoke(System.IAsyncResult)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpression.Invoke(Hl7.Fhir.ElementModel.ITypedElement,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpressionExtensions.IsBoolean(Hl7.FhirPath.CompiledExpression,System.Boolean,Hl7.Fhir.ElementModel.ITypedElement,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpressionExtensions.IsTrue(Hl7.FhirPath.CompiledExpression,Hl7.Fhir.ElementModel.ITypedElement,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpressionExtensions.Predicate(Hl7.FhirPath.CompiledExpression,Hl7.Fhir.ElementModel.ITypedElement,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.CompiledExpressionExtensions.Scalar(Hl7.FhirPath.CompiledExpression,Hl7.Fhir.ElementModel.ITypedElement,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.#ctor(Hl7.Fhir.ElementModel.ITypedElement,Hl7.Fhir.ElementModel.ITypedElement,System.Collections.Generic.IDictionary{System.String,System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement}})
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.#ctor(Hl7.Fhir.ElementModel.ITypedElement,Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.#ctor(Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.get_Environment
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.get_Resource
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.get_RootResource
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.EvaluationContext.get_Tracer
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
CP0002
M:Hl7.FhirPath.EvaluationContext.WithResourceOverrides(Hl7.Fhir.ElementModel.ITypedElement,Hl7.Fhir.ElementModel.ITypedElement)
@@ -267,6 +435,76 @@
lib/net8.0/Hl7.Fhir.Base.dll
true
+
+ CP0002
+ M:Hl7.FhirPath.Expressions.SymbolTableExtensions.AddVar(Hl7.FhirPath.Expressions.SymbolTable,System.String,Hl7.Fhir.ElementModel.ITypedElement)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.FhirPathCompilerCache.IsBoolean(Hl7.Fhir.ElementModel.ITypedElement,System.String,System.Boolean,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.FhirPathCompilerCache.IsTrue(Hl7.Fhir.ElementModel.ITypedElement,System.String,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.FhirPathCompilerCache.Predicate(Hl7.Fhir.ElementModel.ITypedElement,System.String,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.FhirPathCompilerCache.Scalar(Hl7.Fhir.ElementModel.ITypedElement,System.String,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.FhirPathCompilerCache.Select(Hl7.Fhir.ElementModel.ITypedElement,System.String,Hl7.FhirPath.EvaluationContext)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.Functions.EqualityOperators.IsEqualTo(Hl7.Fhir.ElementModel.ITypedElement,Hl7.Fhir.ElementModel.ITypedElement,System.Boolean)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.Functions.EqualityOperators.IsEqualTo(System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement},System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement},System.Boolean)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.Functions.EqualityOperators.IsEquivalentTo(Hl7.Fhir.ElementModel.ITypedElement,Hl7.Fhir.ElementModel.ITypedElement,System.Boolean)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
+
+ CP0002
+ M:Hl7.FhirPath.Functions.EqualityOperators.IsEquivalentTo(System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement},System.Collections.Generic.IEnumerable{Hl7.Fhir.ElementModel.ITypedElement},System.Boolean)
+ lib/net8.0/Hl7.Fhir.Base.dll
+ lib/net8.0/Hl7.Fhir.Base.dll
+ true
+
CP0006
M:Hl7.Fhir.ElementModel.ITypedElement.Children(System.String)
diff --git a/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs b/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs
index 88a994434a..181fd3d80d 100644
--- a/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs
+++ b/src/Hl7.Fhir.Base/ElementModel/ElementNodeExtensions.cs
@@ -9,6 +9,7 @@
#nullable enable
using Hl7.Fhir.ElementModel.Adapters;
+using Hl7.Fhir.Model;
using Hl7.Fhir.Specification;
using Hl7.Fhir.Utility;
using System;
@@ -110,8 +111,11 @@ public static IReadOnlyCollection ChildDefinitions(th
return new List();
}
- public static ScopedNode ToScopedNode(this ITypedElement node) =>
- node as ScopedNode ?? new ScopedNode(node);
+ public static IScopedNode ToScopedNode(this ITypedElement node) =>
+ node as IScopedNode ?? new ScopedNode(node);
+
+ internal static IEnumerable ToScopedNodes(this IEnumerable nodes) =>
+ nodes.Select(n => n.ToScopedNode());
}
}
diff --git a/src/Hl7.Fhir.Base/FhirPath/CompiledExpression.cs b/src/Hl7.Fhir.Base/FhirPath/CompiledExpression.cs
index 54072a9c50..aac1586cba 100644
--- a/src/Hl7.Fhir.Base/FhirPath/CompiledExpression.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/CompiledExpression.cs
@@ -1,13 +1,14 @@
#nullable enable
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using Hl7.FhirPath.Functions;
using System.Collections.Generic;
using System.Linq;
namespace Hl7.FhirPath
{
- public delegate IEnumerable CompiledExpression(ITypedElement root, EvaluationContext ctx);
+ public delegate IEnumerable CompiledExpression(IScopedNode root, EvaluationContext ctx);
public static class CompiledExpressionExtensions
{
@@ -18,7 +19,7 @@ public static class CompiledExpressionExtensions
/// Input at which the expression is evaluated
/// Context of the evaluation
/// The single result of an expression
- public static object? Scalar(this CompiledExpression evaluator, ITypedElement input, EvaluationContext ctx)
+ public static object? Scalar(this CompiledExpression evaluator, IScopedNode input, EvaluationContext ctx)
{
var result = evaluator(input, ctx).Take(2).ToArray();
return result.Any() ? result.Single().Value : null;
@@ -31,7 +32,7 @@ public static class CompiledExpressionExtensions
/// Input at which the expression is evaluated
/// Context of the evaluation
/// True if expression returns true of empty, otheriwse false
- public static bool Predicate(this CompiledExpression evaluator, ITypedElement input, EvaluationContext ctx)
+ public static bool Predicate(this CompiledExpression evaluator, IScopedNode input, EvaluationContext ctx)
{
var result = evaluator(input, ctx).BooleanEval();
return result is null || result.Value;
@@ -44,7 +45,7 @@ public static bool Predicate(this CompiledExpression evaluator, ITypedElement in
/// Input at which the expression is evaluated
/// Context of the evaluation
/// True if expression returns true , and false if expression returns empty of false.
- public static bool IsTrue(this CompiledExpression evaluator, ITypedElement input, EvaluationContext ctx)
+ public static bool IsTrue(this CompiledExpression evaluator, IScopedNode input, EvaluationContext ctx)
{
var result = evaluator(input, ctx).BooleanEval();
return result is not null && result.Value;
@@ -59,7 +60,7 @@ public static bool IsTrue(this CompiledExpression evaluator, ITypedElement input
/// Input at which the expression is evaluated
/// Context of the evaluation
/// True if the result of an expression is equal to a given boolean, otherwise false
- public static bool IsBoolean(this CompiledExpression evaluator, bool value, ITypedElement input, EvaluationContext ctx)
+ public static bool IsBoolean(this CompiledExpression evaluator, bool value, IScopedNode input, EvaluationContext ctx)
{
var result = evaluator(input, ctx).BooleanEval();
return result is not null && result.Value == value;
diff --git a/src/Hl7.Fhir.Base/FhirPath/ElementNavFhirExtensions.cs b/src/Hl7.Fhir.Base/FhirPath/ElementNavFhirExtensions.cs
index 5126d3ad2e..f2317b2c18 100644
--- a/src/Hl7.Fhir.Base/FhirPath/ElementNavFhirExtensions.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/ElementNavFhirExtensions.cs
@@ -39,16 +39,16 @@ public static void PrepareFhirSymbolTableFunctions()
public static SymbolTable AddFhirExtensions(this SymbolTable t)
{
- t.Add("hasValue", (ITypedElement f) => f.HasValue(), doNullProp: false);
+ t.Add("hasValue", (IScopedNode f) => f.HasValue(), doNullProp: false);
t.Add("resolve", (IScopedNode f, EvaluationContext ctx) => resolver(f, ctx), doNullProp: false);
t.Add("resolve", (IEnumerable f, EvaluationContext ctx) => f.Select(fi => resolver(fi, ctx)), doNullProp: false);
- t.Add("memberOf", (ITypedElement input, string valueset, EvaluationContext ctx) => MemberOf(input, valueset, ctx), doNullProp: false);
+ t.Add("memberOf", (IScopedNode input, string valueset, EvaluationContext ctx) => MemberOf(input, valueset, ctx), doNullProp: false);
// Pre-normative this function was called htmlchecks, normative is htmlChecks
// lets keep both to keep everyone happy.
- t.Add("htmlchecks", (ITypedElement f) => f.HtmlChecks(), doNullProp: false);
- t.Add("htmlChecks", (ITypedElement f) => f.HtmlChecks(), doNullProp: false);
+ t.Add("htmlchecks", (IScopedNode f) => f.HtmlChecks(), doNullProp: false);
+ t.Add("htmlChecks", (IScopedNode f) => f.HtmlChecks(), doNullProp: false);
t.Add("lowBoundary", (decimal d, long precision) => AdjustBoundaryDecimal(d, precision, substract), doNullProp: false);
t.Add("lowBoundary", (decimal d) => AdjustBoundaryDecimal(d, null, substract), doNullProp: false);
@@ -81,14 +81,14 @@ public static SymbolTable AddFhirExtensions(this SymbolTable t)
///
///
///
- public static bool HasValue(this ITypedElement focus) => focus?.Value is not null;
+ public static bool HasValue(this IScopedNode focus) => focus?.Value is not null;
///
/// Check if the node has a value, and not just extensions.
///
///
///
- public static bool HtmlChecks(this ITypedElement focus)
+ public static bool HtmlChecks(this IScopedNode focus)
{
if (focus?.Value is null) return false;
@@ -96,7 +96,7 @@ public static bool HtmlChecks(this ITypedElement focus)
return XHtml.IsValidNarrativeXhtml(focus.Value.ToString()!);
}
- public static IEnumerable ToFhirValues(this IEnumerable results)
+ public static IEnumerable ToFhirValues(this IEnumerable results)
{
return results.Select(r =>
{
@@ -268,7 +268,7 @@ internal static P.Time BoundaryTime(P.Time time, long? precision, int minutes, i
/// EvaluationContext of the FhirPath compiler
/// See summary
///
- internal static bool? MemberOf(ITypedElement input, string valueset, EvaluationContext ctx)
+ internal static bool? MemberOf(IScopedNode input, string valueset, EvaluationContext ctx)
{
var service = (ctx is FhirEvaluationContext fctx ? fctx.TerminologyService : null)
?? throw new ArgumentNullException(nameof(ctx), "The 'memberOf' function cannot be executed because the FhirEvaluationContext does not include a TerminologyService.");
@@ -278,7 +278,7 @@ internal static P.Time BoundaryTime(P.Time time, long? precision, int minutes, i
inParams = input.InstanceType switch
{
- "code" when input is ScopedNode sn => inParams.WithCode(code: sn.Value as string, context: sn.LocalLocation),
+ "code" => inParams.WithCode(code: input.Value as string, context: input.GetLocalLocation()),
"Coding" => inParams.WithCoding(input.ParseCoding()),
"CodeableConcept" => inParams.WithCodeableConcept(input.ParseCodeableConcept()),
"string" or "System.String" => inParams.WithCode(code: input.Value as string, context: "No context available"),
diff --git a/src/Hl7.Fhir.Base/FhirPath/EvaluationContext.cs b/src/Hl7.Fhir.Base/FhirPath/EvaluationContext.cs
index 9b71ec64f2..b0d0a5ab05 100644
--- a/src/Hl7.Fhir.Base/FhirPath/EvaluationContext.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/EvaluationContext.cs
@@ -1,4 +1,5 @@
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using System;
using System.Collections.Generic;
@@ -22,7 +23,7 @@ public EvaluationContext()
///
/// The data that will be represented by %resource
[Obsolete("%resource and %rootResource are inferred from scoped nodes by the evaluator. If you do not have access to a scoped node, or if you wish to explicitly override this behaviour, use the EvaluationContext.WithResourceOverrides() method.")]
- public EvaluationContext(ITypedElement? resource) : this(resource, null) { }
+ public EvaluationContext(IScopedNode? resource) : this(resource, null) { }
///
/// Create an EvaluationContext with the given value for %resource and %rootResource.
@@ -30,14 +31,14 @@ public EvaluationContext(ITypedElement? resource) : this(resource, null) { }
/// The data that will be represented by %resource.
/// The data that will be represented by %rootResource.
[Obsolete("%resource and %rootResource are inferred from scoped nodes by the evaluator. If you do not have access to a scoped node, or if you wish to explicitly override this behaviour, use the EvaluationContext.WithResourceOverrides() method.")]
- public EvaluationContext(ITypedElement? resource, ITypedElement? rootResource)
+ public EvaluationContext(IScopedNode? resource, IScopedNode? rootResource)
{
Resource = resource;
RootResource = rootResource ?? resource;
}
[Obsolete("%resource and %rootResource are inferred from scoped nodes by the evaluator. If you do not have access to a scoped node, or if you wish to explicitly override this behaviour, use the EvaluationContext.WithResourceOverrides() method. Environment can be set explicitly after construction of the base context")]
- public EvaluationContext(ITypedElement? resource, ITypedElement? rootResource, IDictionary> environment) : this(resource, rootResource)
+ public EvaluationContext(IScopedNode? resource, IScopedNode? rootResource, IDictionary> environment) : this(resource, rootResource)
{
Environment = environment;
}
@@ -45,27 +46,27 @@ public EvaluationContext(ITypedElement? resource, ITypedElement? rootResource, I
///
/// The data represented by %rootResource.
///
- public ITypedElement? RootResource { get; set; }
+ public IScopedNode? RootResource { get; set; }
///
/// The data represented by %resource.
///
- public ITypedElement? Resource { get; set; }
+ public IScopedNode? Resource { get; set; }
///
/// The environment variables that are available to the FHIRPath expressions.
///
- public IDictionary> Environment { get; set; } = new Dictionary>();
+ public IDictionary> Environment { get; set; } = new Dictionary>();
///
/// A delegate that handles the output for the trace() function.
///
- public Action>? Tracer { get; set; }
+ public Action>? Tracer { get; set; }
}
public static class EvaluationContextExtensions
{
- public static T WithResourceOverrides(this T context, ITypedElement? resource, ITypedElement? rootResource = null) where T : EvaluationContext
+ public static T WithResourceOverrides(this T context, IScopedNode? resource, IScopedNode? rootResource = null) where T : EvaluationContext
{
context.Resource = resource;
context.RootResource = rootResource ?? resource;
diff --git a/src/Hl7.Fhir.Base/FhirPath/Expressions/Closure.cs b/src/Hl7.Fhir.Base/FhirPath/Expressions/Closure.cs
index f6d789aa73..a81220b239 100644
--- a/src/Hl7.Fhir.Base/FhirPath/Expressions/Closure.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/Expressions/Closure.cs
@@ -8,6 +8,7 @@
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using System.Collections.Generic;
namespace Hl7.FhirPath.Expressions
@@ -20,23 +21,14 @@ public Closure()
public EvaluationContext EvaluationContext { get; private set; }
- public static Closure Root(ITypedElement root, EvaluationContext ctx = null)
+ public static Closure Root(IScopedNode root, EvaluationContext ctx = null)
{
var newContext = ctx ?? new EvaluationContext();
-
- var node = root as ScopedNode;
-
- newContext.Resource ??= node != null // if the value has been manually set, we do nothing. Otherwise, if the root is a scoped node:
- ? getResourceFromNode(node) // we infer the resource from the scoped node
- : (root?.Definition?.IsResource is true // if we do not have a scoped node, we see if this is even a resource to begin with
- ? root // if it is, we use the root as the resource
- : null // if not, this breaks the spec in every way (but we will still continue, hopefully we do not need %resource or %rootResource)
- );
+
+ newContext.Resource ??= root.GetResourceContext();
// Same thing, but we copy the resource into the root resource if we cannot infer it from the node.
- newContext.RootResource ??= node != null
- ? getRootResourceFromNode(node)
- : newContext.Resource;
+ newContext.RootResource ??= root.GetRootResourceContext();
var newClosure = new Closure() { EvaluationContext = ctx ?? new EvaluationContext() };
@@ -49,7 +41,7 @@ public static Closure Root(ITypedElement root, EvaluationContext ctx = null)
newClosure.SetThis(input);
newClosure.SetThat(input);
- newClosure.SetIndex(ElementNode.CreateList(0));
+ newClosure.SetIndex([new Integer(0)]);
newClosure.SetOriginalContext(input);
if (newContext.Resource != null) newClosure.SetResource(new[] { newContext.Resource });
@@ -58,9 +50,9 @@ public static Closure Root(ITypedElement root, EvaluationContext ctx = null)
return newClosure;
}
- private Dictionary> _namedValues = new Dictionary>();
+ private Dictionary> _namedValues = new ();
- public virtual void SetValue(string name, IEnumerable value)
+ public virtual void SetValue(string name, IEnumerable value)
{
_namedValues.Remove(name);
_namedValues.Add(name, value);
@@ -79,10 +71,10 @@ public virtual Closure Nest()
}
- public virtual IEnumerable ResolveValue(string name)
+ public virtual IEnumerable ResolveValue(string name)
{
// First, try to directly get "normal" values
- _namedValues.TryGetValue(name, out IEnumerable result);
+ _namedValues.TryGetValue(name, out IEnumerable result);
if (result != null) return result;
diff --git a/src/Hl7.Fhir.Base/FhirPath/Expressions/ClosureExtensions.cs b/src/Hl7.Fhir.Base/FhirPath/Expressions/ClosureExtensions.cs
index 1854b16ff3..b4fdc02353 100644
--- a/src/Hl7.Fhir.Base/FhirPath/Expressions/ClosureExtensions.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/Expressions/ClosureExtensions.cs
@@ -7,41 +7,42 @@
*/
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using System.Collections.Generic;
namespace Hl7.FhirPath.Expressions
{
internal static class ClosureExtensions
{
- public static IEnumerable GetThis(this Closure ctx)
+ public static IEnumerable GetThis(this Closure ctx)
{
return ctx.ResolveValue("builtin.this");
}
- public static void SetThis(this Closure ctx, IEnumerable value)
+ public static void SetThis(this Closure ctx, IEnumerable value)
{
ctx.SetValue("builtin.this", value);
}
- public static IEnumerable GetTotal(this Closure ctx)
+ public static IEnumerable GetTotal(this Closure ctx)
{
return ctx.ResolveValue("builtin.total");
}
- public static void SetTotal(this Closure ctx, IEnumerable value)
+ public static void SetTotal(this Closure ctx, IEnumerable value)
{
ctx.SetValue("builtin.total", value);
}
- public static IEnumerable GetThat(this Closure ctx)
+ public static IEnumerable GetThat(this Closure ctx)
{
return ctx.ResolveValue("builtin.that");
}
- public static void SetThat(this Closure ctx, IEnumerable value)
+ public static void SetThat(this Closure ctx, IEnumerable value)
{
ctx.SetValue("builtin.that", value);
}
@@ -49,7 +50,7 @@ public static void SetThat(this Closure ctx, IEnumerable value)
///
/// The original node that was passed to the evaluation engine before starting evaluation.
///
- public static void SetOriginalContext(this Closure ctx, IEnumerable value)
+ public static void SetOriginalContext(this Closure ctx, IEnumerable value)
{
ctx.SetValue("context", value);
}
@@ -59,7 +60,7 @@ public static void SetOriginalContext(this Closure ctx, IEnumerable
- public static void SetResource(this Closure ctx, IEnumerable value)
+ public static void SetResource(this Closure ctx, IEnumerable value)
{
ctx.SetValue("resource", value);
}
@@ -68,29 +69,29 @@ public static void SetResource(this Closure ctx, IEnumerable valu
/// When a DomainResource contains another resource, and that contained resource is the focus (%resource)
/// then %rootResource refers to the container resource.
///
- public static void SetRootResource(this Closure ctx, IEnumerable value)
+ public static void SetRootResource(this Closure ctx, IEnumerable value)
{
ctx.SetValue("rootResource", value);
}
- public static IEnumerable GetOriginalContext(this Closure ctx)
+ public static IEnumerable GetOriginalContext(this Closure ctx)
{
return ctx.ResolveValue("context");
}
- public static IEnumerable GetResource(this Closure ctx)
+ public static IEnumerable GetResource(this Closure ctx)
{
return ctx.ResolveValue("resource");
}
- public static IEnumerable GetRootResource(this Closure ctx)
+ public static IEnumerable GetRootResource(this Closure ctx)
{
return ctx.ResolveValue("rootResource");
}
- public static Closure Nest(this Closure ctx, IEnumerable input)
+ public static Closure Nest(this Closure ctx, IEnumerable input)
{
var nested = ctx.Nest();
nested.SetThat(input);
@@ -98,12 +99,12 @@ public static Closure Nest(this Closure ctx, IEnumerable input)
return nested;
}
- public static void SetIndex(this Closure ctx, IEnumerable value)
+ public static void SetIndex(this Closure ctx, IEnumerable value)
{
ctx.SetValue("builtin.index", value);
}
- public static IEnumerable GetIndex(this Closure ctx)
+ public static IEnumerable GetIndex(this Closure ctx)
{
return ctx.ResolveValue("builtin.index");
}
diff --git a/src/Hl7.Fhir.Base/FhirPath/Expressions/DynaDispatcher.cs b/src/Hl7.Fhir.Base/FhirPath/Expressions/DynaDispatcher.cs
index 5548c9a249..f25112f166 100644
--- a/src/Hl7.Fhir.Base/FhirPath/Expressions/DynaDispatcher.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/Expressions/DynaDispatcher.cs
@@ -6,6 +6,7 @@
* available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE
*/
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using Hl7.Fhir.Utility;
using System;
using System.Collections.Generic;
@@ -25,18 +26,18 @@ public DynaDispatcher(string name, SymbolTable scope)
private readonly string _name;
private readonly SymbolTable _scope;
- public IEnumerable Dispatcher(Closure context, IEnumerable args)
+ public IEnumerable Dispatcher(Closure context, IEnumerable args)
{
- var actualArgs = new List>();
+ var actualArgs = new List>();
var focus = args.First()(context, InvokeeFactory.EmptyArgs);
- if (!focus.Any()) return ElementNode.EmptyList;
+ if (!focus.Any()) return [];
actualArgs.Add(focus);
var newCtx = context.Nest(focus);
actualArgs.AddRange(args.Skip(1).Select(a => a(newCtx, InvokeeFactory.EmptyArgs)));
- if (actualArgs.Any(aa => !aa.Any())) return ElementNode.EmptyList;
+ if (actualArgs.Any(aa => !aa.Any())) return [];
var entry = _scope.DynamicGet(_name, actualArgs);
diff --git a/src/Hl7.Fhir.Base/FhirPath/Expressions/EvaluatorVisitor.cs b/src/Hl7.Fhir.Base/FhirPath/Expressions/EvaluatorVisitor.cs
index 4c4fa60ab8..96a53c604f 100644
--- a/src/Hl7.Fhir.Base/FhirPath/Expressions/EvaluatorVisitor.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/Expressions/EvaluatorVisitor.cs
@@ -6,10 +6,12 @@
* available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE
*/
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using Hl7.Fhir.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
using FP = Hl7.FhirPath.Expressions;
namespace Hl7.FhirPath.Expressions
@@ -24,9 +26,10 @@ public EvaluatorVisitor(SymbolTable symbols)
}
+ [TemporarilyChanged] // we should refactor ConstantExpression to use IScopedNode too...
public override Invokee VisitConstant(FP.ConstantExpression expression)
{
- return InvokeeFactory.Return(ElementNode.ForPrimitive(expression.Value));
+ return InvokeeFactory.Return(ElementNode.ForPrimitive(expression.Value).ToScopedNode());
}
public override Invokee VisitFunctionCall(FP.FunctionCallExpression expression)
@@ -47,7 +50,7 @@ public override Invokee VisitFunctionCall(FP.FunctionCallExpression expression)
public override Invokee VisitNewNodeListInit(FP.NewNodeListInitExpression expression)
{
- return InvokeeFactory.Return(ElementNode.EmptyList);
+ return InvokeeFactory.Return([]);
}
public override Invokee VisitVariableRef(FP.VariableRefExpression expression)
@@ -82,7 +85,7 @@ public override Invokee VisitVariableRef(FP.VariableRefExpression expression)
return chainResolves;
- IEnumerable chainResolves(Closure context, IEnumerable invokees)
+ IEnumerable chainResolves(Closure context, IEnumerable invokees)
{
return context.ResolveValue(expression.Name) ?? resolve(Symbols, expression.Name, Enumerable.Empty())(context, []);
}
diff --git a/src/Hl7.Fhir.Base/FhirPath/Expressions/Invokee.cs b/src/Hl7.Fhir.Base/FhirPath/Expressions/Invokee.cs
index a89c57d534..c414fbeed8 100644
--- a/src/Hl7.Fhir.Base/FhirPath/Expressions/Invokee.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/Expressions/Invokee.cs
@@ -7,6 +7,7 @@
*/
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using Hl7.FhirPath.Functions;
using System;
using System.Collections.Generic;
@@ -14,43 +15,42 @@
namespace Hl7.FhirPath.Expressions
{
- internal delegate IEnumerable Invokee(Closure context, IEnumerable arguments);
+ internal delegate IEnumerable Invokee(Closure context, IEnumerable arguments);
internal static class InvokeeFactory
{
public static readonly IEnumerable EmptyArgs = Enumerable.Empty();
-
- public static IEnumerable GetThis(Closure context, IEnumerable _)
+ public static IEnumerable GetThis(Closure context, IEnumerable _)
{
return context.GetThis();
}
- public static IEnumerable GetTotal(Closure context, IEnumerable _)
+ public static IEnumerable GetTotal(Closure context, IEnumerable _)
{
return context.GetTotal();
}
- public static IEnumerable GetContext(Closure context, IEnumerable _)
+ public static IEnumerable GetContext(Closure context, IEnumerable _)
{
return context.GetOriginalContext();
}
- public static IEnumerable GetResource(Closure context, IEnumerable _)
+ public static IEnumerable GetResource(Closure context, IEnumerable _)
{
return context.GetResource();
}
- public static IEnumerable GetRootResource(Closure context, IEnumerable arguments)
+ public static IEnumerable GetRootResource(Closure context, IEnumerable arguments)
{
return context.GetRootResource();
}
- public static IEnumerable GetThat(Closure context, IEnumerable _)
+ public static IEnumerable GetThat(Closure context, IEnumerable _)
{
return context.GetThat();
}
- public static IEnumerable GetIndex(Closure context, IEnumerable args)
+ public static IEnumerable GetIndex(Closure context, IEnumerable args)
{
return context.GetIndex();
@@ -59,10 +59,7 @@ public static IEnumerable GetIndex(Closure context, IEnumerable(Func func)
{
- return (ctx, args) =>
- {
- return Typecasts.CastTo>(func());
- };
+ return (_, _) => Typecasts.CastTo>(func());
}
public static Invokee Wrap(Func func, bool propNull)
@@ -72,14 +69,14 @@ public static Invokee Wrap(Func func, bool propNull)
if (typeof(A) != typeof(EvaluationContext))
{
var focus = args.First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !focus.Any()) return ElementNode.EmptyList;
+ if (propNull && !focus.Any()) return [];
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus)));
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus)));
}
else
{
A lastPar = (A)(object)ctx.EvaluationContext;
- return Typecasts.CastTo>(func(lastPar));
+ return Typecasts.CastTo>(func(lastPar));
}
};
}
@@ -90,7 +87,7 @@ internal static Invokee WrapWithPropNullForFocus(Func fu
{
// propagate only null for focus
var focus = args.First()(ctx, InvokeeFactory.EmptyArgs);
- if (!focus.Any()) return ElementNode.EmptyList;
+ if (!focus.Any()) return[];
return Wrap(func, false)(ctx, args);
};
@@ -101,19 +98,19 @@ public static Invokee Wrap(Func func, bool propNull)
return (ctx, args) =>
{
var focus = args.First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !focus.Any()) return ElementNode.EmptyList;
+ if (propNull && !focus.Any()) return [];
if (typeof(B) != typeof(EvaluationContext))
{
var argA = args.Skip(1).First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !argA.Any()) return ElementNode.EmptyList;
+ if (propNull && !argA.Any()) return [];
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus), Typecasts.CastTo(argA)));
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus), Typecasts.CastTo(argA)));
}
else
{
B lastPar = (B)(object)ctx.EvaluationContext;
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus), lastPar));
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus), lastPar));
}
};
}
@@ -123,23 +120,23 @@ public static Invokee Wrap(Func func, bool propNull)
return (ctx, args) =>
{
var focus = args.First()((Closure)ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !focus.Any()) return ElementNode.EmptyList;
+ if (propNull && !focus.Any()) return [];
var argA = args.Skip(1).First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !argA.Any()) return ElementNode.EmptyList;
+ if (propNull && !argA.Any()) return [];
if (typeof(C) != typeof(EvaluationContext))
{
var argB = args.Skip(2).First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !argB.Any()) return ElementNode.EmptyList;
+ if (propNull && !argB.Any()) return [];
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus), Typecasts.CastTo(argA),
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus), Typecasts.CastTo(argA),
Typecasts.CastTo(argB)));
}
else
{
C lastPar = (C)(object)ctx.EvaluationContext;
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus),
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus),
Typecasts.CastTo(argA), lastPar));
}
};
@@ -150,26 +147,26 @@ public static Invokee Wrap(Func func, bool propNul
return (ctx, args) =>
{
var focus = args.First()((Closure)ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !focus.Any()) return ElementNode.EmptyList;
+ if (propNull && !focus.Any()) return [];
var argA = args.Skip(1).First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !argA.Any()) return ElementNode.EmptyList;
+ if (propNull && !argA.Any()) return [];
var argB = args.Skip(2).First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !argB.Any()) return ElementNode.EmptyList;
+ if (propNull && !argB.Any()) return [];
if (typeof(D) != typeof(EvaluationContext))
{
var argC = args.Skip(3).First()(ctx, InvokeeFactory.EmptyArgs);
- if (propNull && !argC.Any()) return ElementNode.EmptyList;
+ if (propNull && !argC.Any()) return [];
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus),
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus),
Typecasts.CastTo(argA), Typecasts.CastTo(argB), Typecasts.CastTo(argC)));
}
else
{
D lastPar = (D)(object)ctx.EvaluationContext;
- return Typecasts.CastTo>(func(Typecasts.CastTo(focus),
+ return Typecasts.CastTo>(func(Typecasts.CastTo(focus),
Typecasts.CastTo(argA), Typecasts.CastTo(argB), lastPar));
}
@@ -186,18 +183,18 @@ public static Invokee WrapLogic(Func, Func, bool?> func)
var right = args.Skip(2).First();
// Return function that actually executes the Invokee at the last moment
- return Typecasts.CastTo>(func(() => left(ctx, InvokeeFactory.EmptyArgs).BooleanEval(), () => right(ctx, InvokeeFactory.EmptyArgs).BooleanEval()));
+ return Typecasts.CastTo>(func(() => left(ctx, InvokeeFactory.EmptyArgs).BooleanEval(), () => right(ctx, InvokeeFactory.EmptyArgs).BooleanEval()));
};
}
- public static Invokee Return(ITypedElement value)
+ public static Invokee Return(IScopedNode value)
{
- return (_, __) => (new[] { (ITypedElement)value });
+ return (_, _) => [value];
}
- public static Invokee Return(IEnumerable value)
+ public static Invokee Return(IEnumerable value)
{
- return (_, __) => value;
+ return (_, _) => value;
}
public static Invokee Invoke(string functionName, IEnumerable arguments, Invokee invokee)
@@ -207,7 +204,7 @@ public static Invokee Invoke(string functionName, IEnumerable arguments
try
{
var wrappedArguments = arguments.Skip(1).Select(wrapWithNextContext);
- return invokee(ctx, [arguments.First(),.. wrappedArguments]);
+ return invokee(ctx, [arguments.First(), ..wrappedArguments]);
}
catch (Exception e)
{
diff --git a/src/Hl7.Fhir.Base/FhirPath/Expressions/SymbolTable.cs b/src/Hl7.Fhir.Base/FhirPath/Expressions/SymbolTable.cs
index 7b58ae46d7..605ea30070 100644
--- a/src/Hl7.Fhir.Base/FhirPath/Expressions/SymbolTable.cs
+++ b/src/Hl7.Fhir.Base/FhirPath/Expressions/SymbolTable.cs
@@ -7,6 +7,7 @@
*/
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -159,10 +160,10 @@ public static void AddLogic(this SymbolTable table, string name, Func f) => f.Any());
t.Add("count", (IEnumerable