-
Notifications
You must be signed in to change notification settings - Fork 352
Introduce a fhirpath debug tracer #3210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 17 commits
d24d890
269c6e3
4d45c55
21539a4
b05954f
cf9458b
8cf189b
bea44d0
ba521f3
c0530a4
a84bc97
bdfc37f
7dd77e9
e5754af
28ecc36
07c71d1
29f0eeb
81435f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright (c) 2015, Firely (info@fire.ly) and contributors | ||
* See the file CONTRIBUTORS for details. | ||
* | ||
* This file is licensed under the BSD 3-Clause license | ||
* available at https://raw.githubusercontent.com/FirelyTeam/firely-net-sdk/master/LICENSE | ||
*/ | ||
using Hl7.Fhir.ElementModel; | ||
using Hl7.FhirPath.Expressions; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
|
||
namespace Hl7.FhirPath | ||
{ | ||
|
||
public class DiagnosticsDebugTracer : IDebugTracer | ||
{ | ||
|
||
public void TraceCall( | ||
Expression expr, | ||
IEnumerable<ITypedElement> focus, | ||
IEnumerable<ITypedElement> thisValue, | ||
ITypedElement index, | ||
IEnumerable<ITypedElement> totalValue, | ||
IEnumerable<ITypedElement> result, | ||
IEnumerable<KeyValuePair<string, IEnumerable<ITypedElement>>> variables) | ||
{ | ||
string exprName; | ||
if (expr is IdentifierExpression ie) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this chain of ifs could be refactored a BUNCH. maybe exprName = expr switch and then a single trace after using the result... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The traces aren't all the same, but pretty close. |
||
return; | ||
|
||
if (expr is ConstantExpression ce) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},constant"); | ||
exprName = "constant"; | ||
} | ||
else if (expr is ChildExpression child) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},{child.ChildName}"); | ||
exprName = child.ChildName; | ||
} | ||
else if (expr is IndexerExpression indexer) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},[]"); | ||
exprName = "[]"; | ||
} | ||
else if (expr is UnaryExpression ue) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},{ue.Op}"); | ||
exprName = ue.Op; | ||
} | ||
else if (expr is BinaryExpression be) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},{be.Op}"); | ||
exprName = be.Op; | ||
} | ||
else if (expr is FunctionCallExpression fe) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},{fe.FunctionName}"); | ||
exprName = fe.FunctionName; | ||
} | ||
else if (expr is NewNodeListInitExpression) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},{{}} (empty)"); | ||
exprName = "{}"; | ||
} | ||
else if (expr is AxisExpression ae) | ||
{ | ||
if (ae.AxisName == "that") | ||
return; | ||
Trace.WriteLine($"Evaluated: {ae.AxisName} results: {result.Count()}"); | ||
exprName = "$" + ae.AxisName; | ||
} | ||
else if (expr is VariableRefExpression ve) | ||
{ | ||
Trace.WriteLine($"{expr.Location.LineNumber},{expr.Location.LinePosition},%{ve.Name}"); | ||
exprName = "%" + ve.Name; | ||
} | ||
else | ||
{ | ||
exprName = expr.GetType().Name; | ||
#if DEBUG | ||
Debugger.Break(); | ||
#endif | ||
throw new Exception($"Unknown expression type: {expr.GetType().Name}"); | ||
brianpos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Trace.WriteLine($"Evaluated: {expr} results: {result.Count()}"); | ||
} | ||
|
||
if (focus != null) | ||
{ | ||
foreach (var item in focus) | ||
{ | ||
DebugTraceValue($"$focus", item); | ||
} | ||
} | ||
|
||
if (thisValue != null) | ||
{ | ||
foreach (var item in thisValue) | ||
{ | ||
DebugTraceValue("$this", item); | ||
} | ||
} | ||
|
||
if (index != null) | ||
{ | ||
DebugTraceValue("$index", index); | ||
} | ||
|
||
if (totalValue != null) | ||
{ | ||
foreach (var item in totalValue) | ||
{ | ||
DebugTraceValue($"{exprName} »", item); | ||
} | ||
} | ||
|
||
if (result != null) | ||
{ | ||
foreach (var item in result) | ||
{ | ||
DebugTraceValue($"{exprName} »", item); | ||
} | ||
} | ||
} | ||
|
||
private static void DebugTraceValue(string exprName, ITypedElement item) | ||
{ | ||
if (item == null) | ||
return; // possible with a null focus to kick things off | ||
if (item.Location == "@primitivevalue@" || item.Location == "@QuantityAsPrimitiveValue@") | ||
Trace.WriteLine($" {exprName}:\t{item.Value}\t({item.InstanceType})"); | ||
else | ||
Trace.WriteLine($" {exprName}:\t{item.Value}\t({item.InstanceType})\t{item.Location}"); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We aim to have nullability annotations for any new classes. If those could be added, that would be great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added nullability.