public void Visit(UnaryOperatorNode node) { visitor.OnVisit((n, v) => { var r = n as UnaryOperatorNode; if (r != null && r.GetOperator() == node.GetOperator()) { Result = IsSameChildren(r, node); } }); reference.Visit(visitor); }
public UnaryExpressionNode(UnaryOperatorNode @operator, ExpressionNode expression) { if (@operator == null) ThrowHelper.ThrowArgumentNullException(() => @operator); if (expression == null) ThrowHelper.ThrowArgumentNullException(() => expression); Operator = @operator; Expression = expression; AddChildren(Operator, Expression); }
/// <summary> /// Compares skip query nodes. /// </summary> /// <param name="left">Left side of comparison</param> /// <param name="right">Right side of comparison</param> /// <returns>True if equal, otherwise false</returns> //private bool Compare(SkipNode left, SkipNode right) //{ // if (left.ItemType != right.ItemType) return false; // if (!this.Compare(left.Collection, right.Collection)) return false; // return this.Compare(left.Amount, right.Amount); //} /// <summary> /// Compares Unary Operator query nodes. /// </summary> /// <param name="left">Left side of comparison</param> /// <param name="right">Right side of comparison</param> /// <returns>True if equal, otherwise false</returns> private bool Compare(UnaryOperatorNode left, UnaryOperatorNode right) { if (left.OperatorKind != right.OperatorKind) { return(false); } if (left.TypeReference != right.TypeReference) { return(false); } return(this.Compare(left.Operand, right.Operand)); }
/// <summary> /// Visit a UnaryOperatorNode /// </summary> /// <param name="nodeIn">The node to visit</param> /// <returns>The translated expression</returns> public override Expression Visit(UnaryOperatorNode nodeIn) { this.CheckArgumentNull(nodeIn, "UnaryOperatorNode"); switch (nodeIn.OperatorKind) { case UnaryOperatorKind.Not: return(Expression.Not(this.TranslateNode(nodeIn.Operand))); default: throw new NotImplementedException(); } }
public void NegateTypePromotion() { var metadata = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.StronglyTypedDataServiceProviderFactory); this.CombinatorialEngineProvider.RunCombinations( ComputeUnaryTestCases(UnaryOperatorKind.Negate).Concat(ComputeUnaryErrorTestCases(UnaryOperatorKind.Negate)), (testCase) => { string filter = "-" + testCase.Arguments[0] + " le 0"; string errorMessage = null; if (testCase.ExpectedErrorMessage != null) { errorMessage = string.Format(CultureInfo.InvariantCulture, testCase.ExpectedErrorMessage, "Negate"); } var actualFilter = this.BindFilter(metadata, filter, errorMessage); if (errorMessage == null) { this.Assert.IsNotNull(actualFilter, "Filter must not be null."); BinaryOperatorNode binaryOperatorNode = null; if (actualFilter.Expression.InternalKind == InternalQueryNodeKind.Convert) { binaryOperatorNode = ((ConvertNode)actualFilter.Expression).Source as BinaryOperatorNode; } else { binaryOperatorNode = actualFilter.Expression as BinaryOperatorNode; } this.Assert.IsNotNull(binaryOperatorNode, "Expected a binary operator at the top of the filter."); UnaryOperatorNode unaryOperatorNode = null; if (binaryOperatorNode.Left.InternalKind == InternalQueryNodeKind.Convert) { unaryOperatorNode = ((ConvertNode)binaryOperatorNode.Left).Source as UnaryOperatorNode; } else { unaryOperatorNode = binaryOperatorNode.Left as UnaryOperatorNode; } this.Assert.IsNotNull(unaryOperatorNode, "Expected a unary operator as the left argument of the binary operator."); QueryTestUtils.VerifyTypesAreEqual( testCase.ExpectedResultType, unaryOperatorNode.Operand.TypeReference, this.Assert); } }); }
public void Visit(UnaryOperatorNode node) { var paren = node.GetPrecedence() < node.GetValue().GetPrecedence(); source.Append(node.GetOperator()); if (paren) { source.Append("("); } node.GetValue().Visit(this); if (paren) { source.Append(")"); } }
/// <summary> /// Override this method to validate the Not operator. /// </summary> /// <remarks> /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code. /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance. /// </remarks> /// <param name="unaryOperatorNode"></param> /// <param name="settings"></param> public virtual void ValidateUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode, ODataValidationSettings settings) { ValidateQueryNode(unaryOperatorNode.Operand, settings); switch (unaryOperatorNode.OperatorKind) { case UnaryOperatorKind.Negate: case UnaryOperatorKind.Not: if ((settings.AllowedLogicalOperators & AllowedLogicalOperators.Not) != AllowedLogicalOperators.Not) { throw new ODataException(Error.Format(SRResources.NotAllowedLogicalOperator, unaryOperatorNode.OperatorKind, "AllowedLogicalOperators")); } break; } }
private void ValidateUnaryOperatorNode(UnaryOperatorNode node, ValidationSettings settings) { ValidateQueryNode(node.Operand, settings); switch (node.OperatorKind) { case UnaryOperatorKind.Negate: case UnaryOperatorKind.Not: if (!settings.AllowedOperators.HasFlag(AllowedOperators.Not)) { throw new ODataException($"The '{node.OperatorKind}' logical operator is not allowed."); } break; } }
private int VisitUnaryOperatorNode(UnaryOperatorNode node) { var opType = node.Op.Type; switch (opType) { case TokenType.PLUS: return(+(int)Visit(node.Expression)); case TokenType.MINUS: return(-(int)Visit(node.Expression)); default: throw new InterpretationException($"Invalid node token type: {node.Op.Type}"); } }
public override ICriterion Visit(UnaryOperatorNode nodeIn) { if (nodeIn.OperatorKind != UnaryOperatorKind.Not) { return(null); } var criterion = nodeIn.Operand.Accept <ICriterion>(this); if (null == criterion) { return(null); } return(Restrictions.Not(criterion)); }
private static Filter BindUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode) { switch (unaryOperatorNode.OperatorKind) { case UnaryOperatorKind.Negate: throw new NotSupportedException("The Negate arithmetic operator isn't supported."); case UnaryOperatorKind.Not: _applyLogicalNegation = true; break; default: throw new NotSupportedException("Unknown UnaryOperatorKind."); } return(Bind(unaryOperatorNode.Operand)); }
/// <summary> /// Override this method to validate the Not operator. /// </summary> /// <remarks> /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code. /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance. /// </remarks> /// <param name="unaryOperatorNode"></param> /// <param name="settings"></param> public virtual void ValidateUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode, ODataValidationSettings settings) { ValidateQueryNode(unaryOperatorNode.Operand, settings); switch (unaryOperatorNode.OperatorKind) { case UnaryOperatorKind.Negate: case UnaryOperatorKind.Not: if ((settings.AllowedLogicalOperators & AllowedLogicalOperators.Not) != AllowedLogicalOperators.Not) { throw new ODataException(Error.Format(SRResources.NotAllowedLogicalOperator, unaryOperatorNode.OperatorKind, "AllowedLogicalOperators")); } break; default: throw Error.NotSupported(SRResources.UnaryNodeValidationNotSupported, unaryOperatorNode.OperatorKind, typeof(FilterQueryValidator).Name); } }
/// <summary> /// Binds a <see cref="UnaryOperatorNode"/> to create a LINQ <see cref="Expression"/> that /// represents the semantics of the <see cref="UnaryOperatorNode"/>. /// </summary> /// <param name="unaryOperatorNode">The node to bind.</param> /// <returns>The LINQ <see cref="Expression"/> created.</returns> public virtual Expression BindUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode) { // No need to handle null-propagation here as CLR already handles it. // !(null) = null // -(null) = null Expression inner = Bind(unaryOperatorNode.Operand); switch (unaryOperatorNode.OperatorKind) { case UnaryOperatorKind.Negate: return(Expression.Negate(inner)); case UnaryOperatorKind.Not: return(Expression.Not(inner)); default: throw Error.NotSupported(SRResources.QueryNodeBindingNotSupported, unaryOperatorNode.Kind, typeof(FilterBinder).Name); } }
public void NotTypePromotion() { var metadata = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.StronglyTypedDataServiceProviderFactory); // run over all operator kinds (not, negate) // use all combinations with the same argument types (plain and nullable) this.CombinatorialEngineProvider.RunCombinations( ComputeUnaryTestCases(UnaryOperatorKind.Not).Concat(ComputeUnaryErrorTestCases(UnaryOperatorKind.Not)), (testCase) => { string filter = "not " + testCase.Arguments[0]; string errorMessage = null; if (testCase.ExpectedErrorMessage != null) { errorMessage = string.Format(CultureInfo.InvariantCulture, testCase.ExpectedErrorMessage, "Not"); } var actualFilter = this.BindFilter(metadata, filter, errorMessage); if (errorMessage == null) { this.Assert.IsNotNull(actualFilter, "Filter must not be null."); UnaryOperatorNode unaryOperatorNode = null; if (actualFilter.Expression.InternalKind == InternalQueryNodeKind.Convert) { unaryOperatorNode = ((ConvertNode)actualFilter.Expression).Source as UnaryOperatorNode; } else { unaryOperatorNode = actualFilter.Expression as UnaryOperatorNode; } this.Assert.IsNotNull(unaryOperatorNode, "Expected a unary operator at the top of the filter."); QueryTestUtils.VerifyTypesAreEqual( testCase.ExpectedResultType, unaryOperatorNode.Operand.TypeReference, this.Assert); } }); }
public override QueryNode Visit(UnaryOperatorNode nodeIn) { if (nodeIn.OperatorKind == UnaryOperatorKind.Negate) { this.sql.Append("-("); } else if (nodeIn.OperatorKind == UnaryOperatorKind.Not) { this.sql.Append("NOT("); } QueryNode operand = nodeIn.Operand.Accept(this); this.sql.Append(")"); if (operand != nodeIn.Operand) { return(new UnaryOperatorNode(nodeIn.OperatorKind, operand)); } return(nodeIn); }
private Node ParseUnopNode() { if (_tokenList.Count == 0) { throw new MissingTokenException(TokenType.IntegerLiteralToken); } Node n; //get operator Token unaryOperator = _tokenList[0]; _tokenList.RemoveAt(0); //switch over three different operators and parse the rest as an expression switch (unaryOperator.TokenType) { case TokenType.BitwiseComplementToken: n = new UnaryOperatorNode(OperatorType.BitwiseComplement); n.Children.Add(Parse(NodeType.FactorNode)); break; case TokenType.NegationToken: n = new UnaryOperatorNode(OperatorType.Negation); n.Children.Add(Parse(NodeType.FactorNode)); break; case TokenType.LogicalNegationToken: n = new UnaryOperatorNode(OperatorType.LogicalNegation); n.Children.Add(Parse(NodeType.FactorNode)); break; default: throw new UnexpectedTokenException(TokenType.IntegerLiteralToken, unaryOperator.TokenType); } return(n); }
/// <summary> /// Translates a <see cref="UnaryOperatorNode"/> into a corresponding <see cref="string"/>. /// </summary> /// <param name="node">The node to translate.</param> /// <returns>The translated string.</returns> public override string Visit(UnaryOperatorNode node) { string result = null; if (node.OperatorKind == UnaryOperatorKind.Negate) { result = Constants.SymbolNegate; } // if current translated node is SearchNode, the UnaryOperator should return NOT, or return not if (node.OperatorKind == UnaryOperatorKind.Not) { result = this.searchFlag ? Constants.SearchKeywordNot : Constants.KeywordNot; } if (node.Operand.Kind == QueryNodeKind.Constant || node.Operand.Kind == QueryNodeKind.SearchTerm) { return(string.Concat(result, ' ', this.TranslateNode(node.Operand))); } return(string.Concat(result, Constants.SymbolOpenParen, this.TranslateNode(node.Operand), Constants.SymbolClosedParen)); }
private QueryNode ParseQueryNode() { QueryNode node = null; if (this.tokens.Count == 0) { throw new ODataException(HttpStatusCode.BadRequest, Messages.UnableToParseFilter); } switch (this.tokens.Peek().TokenType) { case TokenType.FunctionName: node = this.ParseFunctionCallNode(); break; case TokenType.UnaryOperator: var token = this.tokens.Dequeue(); node = this.ParseQueryNode(); node = new UnaryOperatorNode(node, token.Value.ToUnaryOperatorKind()); break; case TokenType.OpenParentheses: this.groupingDepth++; this.tokens.Dequeue(); node = this.ParseQueryNode(); break; case TokenType.PropertyName: node = this.ParsePropertyAccessNode(); break; default: throw new NotSupportedException(this.tokens.Peek().TokenType.ToString()); } return(node); }
private QueryNode ParseQueryNode() { if (_tokens.Count == 0) { throw ODataException.BadRequest(ExceptionMessage.UnableToParseFilter("an incomplete filter has been specified"), "$filter"); } QueryNode node; switch (_tokens.Peek().TokenType) { case TokenType.FunctionName: node = ParseFunctionCallNode(); break; case TokenType.OpenParentheses: _groupingDepth++; _tokens.Dequeue(); node = ParseQueryNode(); break; case TokenType.PropertyName: node = ParsePropertyAccessNode(); break; case TokenType.UnaryOperator: Token token = _tokens.Dequeue(); node = ParseQueryNode(); node = new UnaryOperatorNode(node, token.Value.ToUnaryOperatorKind()); break; default: throw ODataException.BadRequest(ExceptionMessage.UnableToParseFilter($"unexpected {_tokens.Peek().Value}", _tokens.Peek().Position), "$filter"); } return(node); }
public override object Visit(UnaryOperatorNode nodeIn) { return(null); }
/// <summary> /// Visit a UnaryOperatorNode /// </summary> /// <param name="nodeIn">the node to visit</param> /// <returns>Defined by the implementer</returns> public virtual T Visit(UnaryOperatorNode nodeIn) { throw new NotImplementedException(); }
private string BindUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode) { return(ToString(unaryOperatorNode.OperatorKind) + "(" + Bind(unaryOperatorNode.Operand) + ")"); }
public void KindIsUnaryOperatorNode() { UnaryOperatorNode unaryOperatorNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); unaryOperatorNode.InternalKind.Should().Be(InternalQueryNodeKind.UnaryOperator); }
private static void VerifyUnaryOperatorQueryNodesAreEqual(UnaryOperatorNode expected, UnaryOperatorNode actual, AssertionHandler assert) { assert.AreEqual(expected.OperatorKind, actual.OperatorKind, "Operator kinds differ."); VerifyQueryNodesAreEqual(expected.Operand, actual.Operand, assert); }
/// <summary> /// Translate an UnaryOperatorNode. /// </summary> /// <param name="nodeIn">The node to be translated.</param> /// <returns>The translated node.</returns> public override QueryNode Visit(UnaryOperatorNode nodeIn) { return(new UnaryOperatorNode(nodeIn.OperatorKind, (SingleValueNode)nodeIn.Operand.Accept(this))); }
/// <summary> /// Translate an UnaryOperatorNode. /// </summary> /// <param name="nodeIn">The node to be translated.</param> /// <returns>The translated node.</returns> public override QueryNode Visit(UnaryOperatorNode nodeIn) { Contract.Assert(nodeIn != null); return(new UnaryOperatorNode(nodeIn.OperatorKind, (SingleValueNode)nodeIn.Operand.Accept(this))); }
public override void ValidateUnaryOperatorNode(UnaryOperatorNode unaryOperatorQueryNode, ODataValidationSettings settings) { IncrementCount("ValidateUnaryOperatorQueryNode"); base.ValidateUnaryOperatorNode(unaryOperatorQueryNode, settings); }
private QueryNode ParseUnary() { if (this.lexer.Token.Kind == QueryTokenKind.Minus || this.lexer.Token.Kind == QueryTokenKind.Not) { QueryTokenKind opKind = this.lexer.Token.Kind; int opPos = this.lexer.Token.Position; this.lexer.NextToken(); if (opKind == QueryTokenKind.Minus && (this.lexer.Token.Kind == QueryTokenKind.IntegerLiteral || this.lexer.Token.Kind == QueryTokenKind.RealLiteral)) { this.lexer.Token.Text = "-" + this.lexer.Token.Text; this.lexer.Token.Position = opPos; return this.ParsePrimary(); } QueryNode expr = this.ParseUnary(); if (opKind == QueryTokenKind.Minus) { expr = new UnaryOperatorNode(UnaryOperatorKind.Negate, expr); } else { expr = new UnaryOperatorNode(UnaryOperatorKind.Not, expr); } return expr; } return this.ParsePrimary(); }
private string BindUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode) { return ToString(unaryOperatorNode.OperatorKind) + "(" + Bind(unaryOperatorNode.Operand) + ")"; }
public static IEnumerable<FilterTestCase> UnaryOperatorTestCases() { // Single unary operator UnaryOperatorNode left = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); yield return new FilterTestCase() { Filter = UnaryOperatorKind.Negate.ToOperatorName() + "(1) le 5", ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, left, new ConstantNode(5)) }; yield return new FilterTestCase() { Filter = UnaryOperatorKind.Not.ToOperatorName() + " true", ExpectedFilterCondition = new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(true)) }; // Two unary operators UnaryOperatorNode inner = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); UnaryOperatorNode outer = new UnaryOperatorNode(UnaryOperatorKind.Negate, inner); yield return new FilterTestCase() { Filter = UnaryOperatorKind.Negate.ToOperatorName() + "(" + UnaryOperatorKind.Negate.ToOperatorName() + "(1)) le 5", ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outer, new ConstantNode(5)) }; UnaryOperatorNode inner2 = new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(true)); yield return new FilterTestCase() { Filter = UnaryOperatorKind.Not.ToOperatorName() + " " + UnaryOperatorKind.Not.ToOperatorName() + " true", ExpectedFilterCondition = new UnaryOperatorNode(UnaryOperatorKind.Not, inner2) }; // Unary and binary operator. UnaryOperatorNode inner3 = new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(true)); yield return new FilterTestCase() { Filter = UnaryOperatorKind.Not.ToOperatorName() + " true " + BinaryOperatorKind.Equal.ToOperatorName() + " false", ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.Equal, inner3, new ConstantNode(false)) }; // With parenthesis BinaryOperatorNode innerBinary = new BinaryOperatorNode(BinaryOperatorKind.Add, new ConstantNode(2), new ConstantNode(3)); UnaryOperatorNode outer2 = new UnaryOperatorNode(UnaryOperatorKind.Negate, innerBinary); yield return new FilterTestCase() { Filter = UnaryOperatorKind.Negate.ToOperatorName() + " (2 " + BinaryOperatorKind.Add.ToOperatorName() + " 3) le 5", ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outer2, new ConstantNode(5)) }; BinaryOperatorNode innerBinary2 = new BinaryOperatorNode(BinaryOperatorKind.Equal, new ConstantNode(true), new ConstantNode(false)); yield return new FilterTestCase() { Filter = UnaryOperatorKind.Not.ToOperatorName() + " (true " + BinaryOperatorKind.Equal.ToOperatorName() + " false)", ExpectedFilterCondition = new UnaryOperatorNode(UnaryOperatorKind.Not, innerBinary2) }; }
/// <summary> /// Binds the specified <see cref="UnaryOperatorNode"/>. /// </summary> /// <param name="unaryOperatorNode">The <see cref="UnaryOperatorNode"/> to bind.</param> protected abstract void Bind(UnaryOperatorNode unaryOperatorNode);
/// <summary> /// Compares skip query nodes. /// </summary> /// <param name="left">Left side of comparison</param> /// <param name="right">Right side of comparison</param> /// <returns>True if equal, otherwise false</returns> //private bool Compare(SkipNode left, SkipNode right) //{ // if (left.ItemType != right.ItemType) return false; // if (!this.Compare(left.Collection, right.Collection)) return false; // return this.Compare(left.Amount, right.Amount); //} /// <summary> /// Compares Unary Operator query nodes. /// </summary> /// <param name="left">Left side of comparison</param> /// <param name="right">Right side of comparison</param> /// <returns>True if equal, otherwise false</returns> private bool Compare(UnaryOperatorNode left, UnaryOperatorNode right) { if (left.OperatorKind != right.OperatorKind) return false; if (left.TypeReference != right.TypeReference) return false; return this.Compare(left.Operand, right.Operand); }
public void OperandSetCorrectly() { UnaryOperatorNode unaryOperatorNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); unaryOperatorNode.Operand.ShouldBeConstantQueryNode(1); }
public void TypeReferenceSetFromOperand() { UnaryOperatorNode unaryOperatorNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); unaryOperatorNode.TypeReference.Should().Be(new ConstantNode(1).TypeReference); }
public void TypeReferenceSetFromOperand() { UnaryOperatorNode unaryOperatorNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); Assert.True(unaryOperatorNode.TypeReference.IsEquivalentTo(new ConstantNode(1).TypeReference)); }
public void KindIsUnaryOperatorNode() { UnaryOperatorNode unaryOperatorNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1)); Assert.Equal(InternalQueryNodeKind.UnaryOperator, unaryOperatorNode.InternalKind); }
private string BindUnaryOperatorNode(UnaryOperatorNode unaryOperatorNode, ICollection <BinderNode> nodes) { return(ToString(unaryOperatorNode.OperatorKind) + "(" + Bind(unaryOperatorNode.Operand, nodes) + ")"); }
public virtual void Visit (UnaryOperatorNode node) { Visit (node as OperatorNode); }
/// <summary> /// Writes unary operator node to string. /// </summary> /// <param name="node">Node to write to string</param> /// <returns>String representation of node.</returns> private static string ToString(UnaryOperatorNode node) { if (node != null) { return tabHelper.Prefix + node.OperatorKind + "(" + tabHelper.Indent(() => ToString(node.Operand)) + tabHelper.Prefix + ")"; } return String.Empty; }