private KeyValuePair <string, Expression> ParseSelectPart(Type thisType, NodeBase node, ParameterExpression thisParam, string parsedString) { string propertyName = null; if (node.NodeType == NodeType.As) { var asNode = (BinaryOperatorNode)node; if (asNode.Right.NodeType != NodeType.Symbol) { throw QueryParseException.Create(node.ParserNode, "Need to specify a property name on left side of as in select expression.", parsedString, null, QueryParseErrorReason.GenericError); } propertyName = ((SymbolNode)asNode.Right).Name; node = asNode.Left; } else { if (!TryGetImplicitPropertyName(node, out propertyName)) { throw QueryParseException.Create(node.ParserNode, $"Unable to infer property name of select expression ({node})", parsedString, null, QueryParseErrorReason.GenericError); } } var exprParser = new NodeTreeToExpressionConverter(this.queryPropertyResolver, parsedString); var lambdaExpression = exprParser.ToLambdaExpression(thisParam, thisParam.WrapAsEnumerable(), Enumerable.Empty <ParameterExpression>(), node); return(new KeyValuePair <string, Expression>(propertyName, lambdaExpression.Body)); }
private Exception CreateParseException(NodeBase node, string message, Exception innerException = null, QueryParseErrorReason?errorReason = null, string memberName = null) { if (node?.ParserNode != null && this.parsedString != null) { return(QueryParseException.Create(node.ParserNode, message, this.parsedString, innerException, errorReason, memberName)); } return(new QueryParseException(message, innerException, QueryParseErrorReason.GenericError, null)); }
private static NodeBase ParseTreeInner(ITree tree, int depth, string parsedString) { depth++; if (tree.Type == 0) { throw QueryParseException.Create(tree, "Parse error", parsedString, null); } if (tree.Type == PomonaQueryParser.PREFIXED_STRING) { var text = tree.Text; var stringPartStart = text.IndexOf('\''); if (stringPartStart == -1) { throw new InvalidOperationException("Unable to parse prefixed literal."); } var prefix = text.Substring(0, stringPartStart); var value = text.Substring(stringPartStart + 1, text.Length - stringPartStart - 2); switch (prefix) { case "t": return(new TypeNameNode(value)); case "guid": return(new GuidNode(Guid.Parse(value))); case "datetime": return(GetDateTimeNode(value)); } } if (IsReduceableBinaryOperator(tree.Type) && tree.ChildCount == 1) { return(ParseTree(tree.GetChild(0), depth, parsedString)); } switch (tree.Type) { case PomonaQueryParser.NOT_OP: return(new NotNode(ParseChildren(tree, depth, parsedString))); case PomonaQueryParser.METHOD_CALL: return(new MethodCallNode(tree.GetChild(0).Text, ParseChildren(tree, depth, parsedString, 1))); case PomonaQueryParser.INDEXER_ACCESS: return(new IndexerAccessNode(tree.GetChild(0).Text, ParseChildren(tree, depth, parsedString, 1))); case PomonaQueryParser.INT: return(new NumberNode(tree.Text)); case PomonaQueryParser.STRING: return(new StringNode(tree.Text)); case PomonaQueryParser.ID: return(new SymbolNode(tree.Text, ParseChildren(tree, depth, parsedString))); case PomonaQueryParser.ROOT: return(ParseTree(tree.GetChild(0), depth, parsedString)); case PomonaQueryParser.LAMBDA_OP: return(new LambdaNode(ParseChildren(tree, depth, parsedString))); case PomonaQueryParser.ARRAY_LITERAL: return(new ArrayNode(ParseChildren(tree, depth, parsedString))); } NodeType nodeType; if (IsBinaryOperator(tree.Type, out nodeType)) { var childNodes = new Queue <NodeBase>(ParseChildren(tree, depth, parsedString)); var expr = childNodes.Dequeue(); while (childNodes.Count > 0) { expr = new BinaryOperatorNode(nodeType, new[] { expr, childNodes.Dequeue() }); } return(expr); } return(new UnhandledNode(tree)); }