示例#1
0
        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;
                }
            }
        }
示例#3
0
        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;
                }
            }
        }
示例#4
0
 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());
 }
示例#5
0
        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));
        }