Skip to content

Commit 3489cfc

Browse files
committed
And remove the out parameter
(discovered that the only place where the evaluation wasn't wrapeed is the dynamic dispatcher, so that one needs to have special handling on the focus to "put it back" as there's no log wapper at that stage - already executed and logged the parameters)
1 parent 31d12ea commit 3489cfc

File tree

7 files changed

+144
-168
lines changed

7 files changed

+144
-168
lines changed

src/Hl7.Fhir.Base/FhirPath/Expressions/Closure.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,45 @@ public Closure(EvaluationContext ctx)
2323
{
2424
EvaluationContext = ctx;
2525
Id = ctx.IncrementClosuresCreatedCount();
26+
_debugTracerActive = ctx.DebugTracer != null;
2627
}
2728

2829
public Closure(Closure parent, EvaluationContext ctx)
2930
{
3031
Parent = parent;
3132
EvaluationContext = ctx;
3233
Id = ctx.IncrementClosuresCreatedCount();
34+
_debugTracerActive = ctx.DebugTracer != null;
3335
}
3436

3537
/// <summary>
3638
/// When the debug/trace is enabled this property is used to record the focus of the closure.
37-
/// It is set in the delegate produced for each node by the evaluator visitor.
38-
/// The value is set <b>immediately before</b> returning the result of the evaluation of the node,
39-
/// <b>after all</b> it's processing, this must be done as the same context is re-used in many
40-
/// cases, and thus needs to be re-set just before it returns from the delegate.
41-
/// The debug tracer uses this information in the wrapped delegate to report not only the
42-
/// result of the expression, but also the other states of the closure, such as the focus,
43-
/// resource, root resource, etc.
44-
/// The $this variable doesn't change within a closure object, so it is not set here.
39+
/// <br/>VALUE IS NOT USED OUTSIDE DEBUG - without debug/tracer, the value is not consistent.
4540
/// </summary>
41+
/// <remarks>
42+
/// It is set in the delegate produced for each node by the evaluator visitor.
43+
/// The debug tracer will reset the focus in the closure after calling the delegate it's wrapping.
44+
/// ensuring that argument evaluation doesn't impact the focus logged in the debug trace in other
45+
/// calls.
46+
/// </remarks>
4647
public IEnumerable<ITypedElement> focus
4748
{
48-
get => _focus;
49+
get
50+
{
51+
if (!_debugTracerActive)
52+
return ElementNode.EmptyList;
53+
return _focus;
54+
}
4955
set
5056
{
57+
if (!_debugTracerActive)
58+
return;
5159
_focus = value;
5260
}
5361
}
5462

5563
private IEnumerable<ITypedElement> _focus;
64+
private bool _debugTracerActive = false;
5665

5766
public EvaluationContext EvaluationContext { get; private set; }
5867

src/Hl7.Fhir.Base/FhirPath/Expressions/DynaDispatcher.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@ public DynaDispatcher(string name, SymbolTable scope)
2626
private readonly string _name;
2727
private readonly SymbolTable _scope;
2828

29-
public FocusCollection Dispatcher(Closure context, IEnumerable<Invokee> args, out FocusCollection focus)
29+
public FocusCollection Dispatcher(Closure context, IEnumerable<Invokee> args)
3030
{
3131
var actualArgs = new List<FocusCollection>();
3232

33-
focus = args.First()(context, InvokeeFactory.EmptyArgs, out _);
33+
var focus = args.First()(context, InvokeeFactory.EmptyArgs);
34+
context.focus = focus;
3435
if (!focus.Any()) return ElementNode.EmptyList;
3536

3637
actualArgs.Add(focus);
3738
var newCtx = context.Nest(focus);
3839

39-
actualArgs.AddRange(args.Skip(1).Select(a => a(newCtx, InvokeeFactory.EmptyArgs, out _)));
40+
actualArgs.AddRange(args.Skip(1).Select(a => a(newCtx, InvokeeFactory.EmptyArgs)));
4041
if (actualArgs.Any(aa => !aa.Any())) return ElementNode.EmptyList;
4142

4243
var entry = _scope.DynamicGet(_name, actualArgs);
@@ -48,8 +49,12 @@ public FocusCollection Dispatcher(Closure context, IEnumerable<Invokee> args, ou
4849
// The Get() here should never fail, since we already know there's a (dynamic) matching candidate
4950
// Need to clean up this duplicate logic later
5051
var argFuncs = actualArgs.Select(InvokeeFactory.Return);
52+
var result = entry(context, argFuncs);
53+
54+
// Dynamically dispatched function arguments aren't wrapped
55+
// for the debug/trace, so need to manually put the focus back
5156
context.focus = focus;
52-
return entry(context, argFuncs, out _);
57+
return result;
5358
}
5459
catch (TargetInvocationException tie)
5560
{

src/Hl7.Fhir.Base/FhirPath/Expressions/EvaluatorVisitor.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ private Invokee WrapForDebugTracer(Invokee invokee, Expression expression)
2121
{
2222
if (_injectDebugHook)
2323
{
24-
return (Closure context, IEnumerable<Invokee> arguments, out FocusCollection focus) => {
24+
return (Closure context, IEnumerable<Invokee> arguments) => {
2525
var oldFocus = context.focus;
26-
var result = invokee(context, arguments, out focus);
26+
var result = invokee(context, arguments);
27+
2728
context.EvaluationContext.DebugTracer?.TraceCall(expression, context.Id, context.focus, context.GetThis(), context.GetIndex()?.FirstOrDefault(), context.GetTotal(), result, context.Variables());
29+
2830
// restore the original focus to the context
2931
context.focus = oldFocus;
3032
return result;
@@ -106,19 +108,18 @@ public override Invokee VisitVariableRef(FP.VariableRefExpression expression)
106108

107109
return WrapForDebugTracer(chainResolves, expression);
108110

109-
FocusCollection chainResolves(Closure context, IEnumerable<Invokee> invokees, out FocusCollection focus)
111+
FocusCollection chainResolves(Closure context, IEnumerable<Invokee> invokees)
110112
{
111113
var value = context.ResolveValue(expression.Name);
112114
if (value != null)
113115
{
114116
// this was in the context, so the scope was $this (the context)
115-
focus = context.GetThis();
116-
context.focus = focus;
117+
context.focus = context.GetThis();
117118
return value;
118119
}
119120
else
120121
{
121-
return resolve(Symbols, expression.Name, Enumerable.Empty<Type>())(context, [], out focus);
122+
return resolve(Symbols, expression.Name, Enumerable.Empty<Type>())(context, []);
122123
}
123124
}
124125
}

0 commit comments

Comments
 (0)