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."); } }
public static SpecificationResult ParseValue(SymbolValue symbolValue) { return(InferPathsFromValue(SpecificationResult.FromValue(symbolValue), symbolValue)); }