public static void CheckExpression(ITypedElement inputNav, Hl7.FhirPath.Expressions.Expression expr, Action <string, bool, string> AppendResults, Action ResetResults) { ExpressionElementContext context = new ExpressionElementContext(inputNav.Name); if (inputNav is dstu2::Hl7.Fhir.ElementModel.IFhirValueProvider pn2) { if (pn2.FhirValue is f2.Questionnaire q) { context._q2 = q; } } else if (inputNav is stu3::Hl7.Fhir.ElementModel.IFhirValueProvider pn3) { if (pn3.FhirValue is f3.Questionnaire q) { context._q3 = q; } } else if (inputNav is r4::Hl7.Fhir.ElementModel.IFhirValueProvider pn4) { if (pn4.FhirValue is f4.Questionnaire q) { context._q4 = q; } } ResetResults(); CheckExpression(expr, "", context, AppendResults); }
private void ButtonCheckExpression_Click(object sender, RoutedEventArgs e) { EvaluationContext evalContext; var inputNav = GetResourceNavigator(out evalContext); if (inputNav == null) { return; } // Don't need to cache this, it is cached in the fhir-client Hl7.FhirPath.Expressions.Expression expr = null; try { expr = FhirPathProcessor._compiler.Parse(textboxExpression.Text); } catch (Exception ex) { SetResults("Expression compilation error:\r\n" + ex.Message, true); return; } if (expr != null) { try { FhirPathProcessor.CheckExpression(inputNav, expr, AppendResults, ResetResults); } catch (Exception ex) { SetResults("Expression Check error:\r\n" + ex.Message, true); return; } } }
private void ButtonCheckExpression_Click(object sender, RoutedEventArgs e) { var inputNav = GetResourceNavigator(); if (inputNav == null) { return; } // Don't need to cache this, it is cached in the fhir-client Hl7.FhirPath.Expressions.Expression expr = null; try { expr = _compiler.Parse(textboxExpression.Text); } catch (Exception ex) { SetResults("Expression compilation error:\r\n" + ex.Message, true); return; } if (expr != null) { try { ExpressionElementContext context = new ExpressionElementContext(inputNav.Name); if (inputNav is dstu2::Hl7.Fhir.ElementModel.PocoNavigator pn2) { if (pn2.FhirValue is f2.Questionnaire q) { context._q2 = q; } } else if (inputNav is stu3::Hl7.Fhir.ElementModel.PocoNavigator pn3) { if (pn3.FhirValue is f3.Questionnaire q) { context._q3 = q; } } ResetResults(); CheckExpression(expr, "", context); } catch (Exception ex) { SetResults("Expression Check error:\r\n" + ex.Message, true); return; } } }
private void OutputExpression(Hl7.FhirPath.Expressions.Expression expr, StringBuilder sb, string prefix) { if (expr is ChildExpression) { var func = expr as ChildExpression; OutputExpression(func.Focus, sb, prefix + "-- "); sb.AppendFormat("{0}{1}\r\n", prefix, func.ChildName); return; } if (expr is FunctionCallExpression) { var func = expr as FunctionCallExpression; sb.AppendFormat("{0}{1}\r\n", prefix, func.FunctionName); OutputExpression(func.Focus, sb, prefix + "-- "); foreach (var item in func.Arguments) { OutputExpression(item, sb, prefix + " "); } return; } //else if (expr is BinaryExpression) //{ // var func = expr as BinaryExpression; // sb.AppendLine(func.FunctionName); // OutputExpression(func.Left, sb); // sb.AppendLine(func.Op); // OutputExpression(func.Right, sb); // return; //} else if (expr is ConstantExpression) { var func = expr as ConstantExpression; sb.AppendFormat("{0}{1} (constant)\r\n", prefix, func.Value.ToString()); return; } else if (expr is VariableRefExpression) { var func = expr as VariableRefExpression; // sb.AppendFormat("{0}{1} (variable ref)\r\n", prefix, func.Name); return; } sb.Append(expr.GetType().ToString()); }
private static ExpressionElementContext CheckExpression(Hl7.FhirPath.Expressions.Expression expr, string prefix, ExpressionElementContext context, Action <string, bool, string> AppendResults) { if (expr is ChildExpression) { var func = expr as ChildExpression; var focusContext = CheckExpression(func.Focus, prefix + "-- ", context, AppendResults); var childContext = focusContext.Child(func.ChildName); if (childContext != null) { if (focusContext._q4 != null) { if (func.ChildName == "item") { childContext._4is = new List <f4.Questionnaire.ItemComponent>(); childContext._4is.AddRange(focusContext._q4.Item); } } if (focusContext._q3 != null) { if (func.ChildName == "item") { childContext._3is = new List <f3.Questionnaire.ItemComponent>(); childContext._3is.AddRange(focusContext._q3.Item); } } if (focusContext._q2 != null) { if (func.ChildName == "group") { childContext._2gs = new List <f2.Questionnaire.GroupComponent>(); childContext._2gs.Add(focusContext._q2.Group); } } if (focusContext._4is != null) { if (func.ChildName == "item") { childContext._4is = new List <f4.Questionnaire.ItemComponent>(); foreach (var item in focusContext._4is) { if (item.Item != null) { childContext._4is.AddRange(item.Item); } } } } if (focusContext._3is != null) { if (func.ChildName == "item") { childContext._3is = new List <f3.Questionnaire.ItemComponent>(); foreach (var item in focusContext._3is) { if (item.Item != null) { childContext._3is.AddRange(item.Item); } } } } if (focusContext._2gs != null) { if (func.ChildName == "group") { childContext._2gs = new List <f2.Questionnaire.GroupComponent>(); foreach (var item in focusContext._2gs) { if (item.Group != null) { childContext._2gs.AddRange(item.Group); } } } else if (func.ChildName == "question") { childContext._2qs = new List <f2.Questionnaire.QuestionComponent>(); foreach (var item in focusContext._2gs) { if (item.Question != null) { childContext._2qs.AddRange(item.Question); } } } } if (focusContext._2qs != null) { if (func.ChildName == "group") { childContext._2gs = new List <f2.Questionnaire.GroupComponent>(); foreach (var item in focusContext._2qs) { if (item.Group != null) { childContext._2gs.AddRange(item.Group); } } } } AppendResults($"{prefix}{func.ChildName}", false, childContext.Tooltip()); return(childContext); } else { AppendResults($"{prefix}{func.ChildName} *invalid property name*", true, null); } return(context); } if (expr is FunctionCallExpression) { var func = expr as FunctionCallExpression; var funcs = _compiler.Symbols.Filter(func.FunctionName, func.Arguments.Count() + 1); if (funcs.Count() == 0 && !(expr is BinaryExpression)) { AppendResults($"{prefix}{func.FunctionName} *invalid function name*", true, null); } else { AppendResults($"{prefix}{func.FunctionName}", false, null); } var focusContext = CheckExpression(func.Focus, prefix + "-- ", context, AppendResults); if (func.FunctionName == "binary.as") { if (func.Arguments.Count() != 2) { AppendResults($"{prefix}{func.FunctionName} INVALID AS Operation", true, null); return(focusContext); } var argContextResult = CheckExpression(func.Arguments.First(), prefix + " ", focusContext, AppendResults); var typeArg = func.Arguments.Skip(1).FirstOrDefault() as ConstantExpression; string typeCast = typeArg?.Value as string; argContextResult.RestrictToType(typeCast); return(argContextResult); } else if (func.FunctionName == "resolve") { // need to check what the available outcomes of resolving this are, and switch types to this } else { // if this is a where operation and the context inside is a linkId = , then check that the linkId is in context if (func.FunctionName == "where" && func.Arguments.Count() == 1 && (func.Arguments.First() as BinaryExpression)?.Op == "=") { var op = func.Arguments.First() as BinaryExpression; var argContextResult = CheckExpression(op, prefix + " ", focusContext, AppendResults); // Filter the values that are not in this set focusContext._4is = argContextResult._4is; focusContext._3is = argContextResult._3is; focusContext._2gs = argContextResult._2gs; focusContext._2qs = argContextResult._2qs; } else { foreach (var item in func.Arguments) { var argContextResult = CheckExpression(item, prefix + " ", focusContext, AppendResults); } } if (func.FunctionName == "binary.=") { ChildExpression prop = (ChildExpression)func.Arguments.Where(a => a is ChildExpression).FirstOrDefault(); ConstantExpression value = (ConstantExpression)func.Arguments.Where(a => a is ConstantExpression).FirstOrDefault(); if (prop?.ChildName == "linkId" && value != null) { var groupLinkIds = focusContext._2gs?.Select(i => i.LinkId).ToArray(); var questionLinkIds = focusContext._2qs?.Select(i => i.LinkId).ToArray(); var item4Ids = focusContext._4is?.Select(i => i.LinkId).ToArray(); var item3Ids = focusContext._3is?.Select(i => i.LinkId).ToArray(); // filter out all of the other linkIds from the list focusContext._4is?.RemoveAll(i => i.LinkId != value.Value as string); focusContext._3is?.RemoveAll(i => i.LinkId != value.Value as string); focusContext._2gs?.RemoveAll(g => g.LinkId != value.Value as string); focusContext._2qs?.RemoveAll(q => q.LinkId != value.Value as string); // Validate that there is an item with this value that is reachable if (focusContext._2gs?.Count() == 0 || focusContext._2qs?.Count() == 0) { // this linkId didn't exist in this context! string toolTip = "Available LinkIds:"; if (groupLinkIds != null) { toolTip += $"\r\nGroup: {String.Join(", ", groupLinkIds)}"; } if (questionLinkIds != null) { toolTip += $"\r\nQuestion: {String.Join(", ", questionLinkIds)}"; } AppendResults($"{prefix}{func.FunctionName} LinkId is not valid in this context", true, toolTip); } if (focusContext._3is?.Count() == 0) { // this linkId didn't exist in this context! string toolTip = "Available LinkIds:"; if (item3Ids != null) { toolTip += $"\r\nItems: {String.Join(", ", item3Ids)}"; } AppendResults($"{prefix}{func.FunctionName} LinkId is not valid in this context", true, toolTip); } if (focusContext._4is?.Count() == 0) { // this linkId didn't exist in this context! string toolTip = "Available LinkIds:"; if (item4Ids != null) { toolTip += $"\r\nItems: {String.Join(", ", item4Ids)}"; } AppendResults($"{prefix}{func.FunctionName} LinkId is not valid in this context", true, toolTip); } } } } return(focusContext); } //else if (expr is BinaryExpression) //{ // var func = expr as BinaryExpression; // sb.AppendLine(func.FunctionName); // CheckExpression(func.Left, sb); // sb.AppendLine(func.Op); // CheckExpression(func.Right, sb); // return; //} else if (expr is ConstantExpression) { var func = expr as ConstantExpression; AppendResults($"{prefix}{func.Value.ToString()} (constant)", false, null); return(null); // context doesn't propogate from this } else if (expr is VariableRefExpression) { var func = expr as VariableRefExpression; // sb.AppendFormat("{0}{1} (variable ref)\r\n", prefix, func.Name); return(context); } AppendResults(expr.GetType().ToString(), false, null); return(context); }
public static Invokee ToEvaluator(this FP.Expression expr, SymbolTable scope) { var compiler = new EvaluatorVisitor(); return(expr.Accept <Invokee>(compiler, scope)); }