public static SpecificationResult ParseSpecification(SymbolTable symbolTable, SpecificationContext context, Expression body)
        {
            if (body is MethodCallExpression methodCall)
            {
                var method = methodCall.Method;

                if (method.DeclaringType == typeof(FactRepository) &&
                    method.Name == nameof(FactRepository.OfType))
                {
                    var type     = method.GetGenericArguments()[0];
                    var factType = type.FactTypeName();

                    var set = FactsOfType(factType, type);
                    var sourceSymbolValue = new SymbolValueSetDefinition(set);
                    var source            = SpecificationResult.FromValue(sourceSymbolValue)
                                            .WithTarget(set);

                    if (methodCall.Arguments.Count == 0)
                    {
                        return(source);
                    }
                    else
                    {
                        return(ParseWhere(source, symbolTable, context, methodCall.Arguments[0]));
                    }
                }
                else if (method.DeclaringType == typeof(Queryable))
                {
                    if (method.Name == nameof(Queryable.Where) && methodCall.Arguments.Count == 2)
                    {
                        var source = ParseSpecification(symbolTable, context, methodCall.Arguments[0]);
                        return(ParseWhere(source, symbolTable, context, methodCall.Arguments[1]));
                    }
                    else if (method.Name == nameof(Queryable.Select) && methodCall.Arguments.Count == 2)
                    {
                        var source = ParseSpecification(symbolTable, context, methodCall.Arguments[0]);
                        return(ParseSelect(source, symbolTable, context, methodCall.Arguments[1]));
                    }
                    else if (method.Name == nameof(Queryable.SelectMany) && methodCall.Arguments.Count == 3)
                    {
                        var source = ParseSpecification(symbolTable, context, methodCall.Arguments[0]);
                        return(ParseSelectMany(source, symbolTable, context, methodCall.Arguments[1], methodCall.Arguments[2]));
                    }
                    else
                    {
                        throw new SpecificationException($"You cannot use {method.Name} in a Jinaga specification.");
                    }
                }
                else
                {
                    throw new SpecificationException($"You cannot use {method.DeclaringType.Name}.{method.Name} in a Jinaga specification.");
                }
            }
            else
            {
                throw new SpecificationException($"You cannot use the syntax {body} in a Jinaga specification.");
            }
        }
 private static SpecificationResult ParseWhere(SpecificationResult source, SymbolTable symbolTable, SpecificationContext context, Expression predicate)
 {
     if (predicate is UnaryExpression {
         Operand : LambdaExpression lambda
     })
Exemple #3
0
        public static (SymbolValue symbolValue, string tag) ParseValue(SymbolTable symbolTable, SpecificationContext context, Expression expression)
        {
            if (expression is NewExpression newBody)
            {
                var names = newBody.Members != null
                    ? newBody.Members.Select(member => member.Name)
                    : newBody.Constructor.GetParameters().Select(parameter => parameter.Name);

                var values = newBody.Arguments
                             .Select(arg => ParseValue(symbolTable, context, arg).symbolValue);
                var fields = names.Zip(values, (name, value) => KeyValuePair.Create(name, value))
                             .ToImmutableDictionary();
                return(new SymbolValueComposite(fields), "");
            }
            else if (expression is MemberInitExpression memberInit)
            {
                var fields = memberInit.Bindings
                             .Select(binding => ParseMemberBinding(symbolTable, context, binding))
                             .ToImmutableDictionary();
                return(new SymbolValueComposite(fields), "");
            }
            else if (expression is MemberExpression {
                Member : PropertyInfo propertyInfo
            } memberExpression)
            {
                switch (ParseValue(symbolTable, context, memberExpression.Expression))
                {
                case (SymbolValueComposite compositeValue, _) :
                    return(compositeValue.GetField(propertyInfo.Name), propertyInfo.Name);

                case (SymbolValueSetDefinition setValue, string tag):
                    var role            = propertyInfo.Name;
                    var predecessorType = propertyInfo.PropertyType.FactTypeName();
                    var setDefinition   = setValue.SetDefinition.AppendChain(role, predecessorType, propertyInfo.PropertyType);
                    return(new SymbolValueSetDefinition(setDefinition), tag);

                default:
                    throw new NotImplementedException();
                }
            }