From 359b08cc79ed89cab1fbc4e2b0b69b94a4e9cd06 Mon Sep 17 00:00:00 2001 From: Florian Hockmann Date: Mon, 12 Mar 2018 21:16:18 +0100 Subject: [PATCH 1/2] TINKERPOP-1919 Merge classes P and TraversalPredicate There is no good reason to keep those two classes separate anymore and having P as the type for step parameters is probably easier to understand for users than TraversalPredicate. --- CHANGELOG.asciidoc | 1 + gremlin-dotnet/glv/P.template | 62 +++++++++- gremlin-dotnet/glv/generate.groovy | 2 +- .../Process/Traversal/GraphTraversal.cs | 20 ++-- .../src/Gremlin.Net/Process/Traversal/P.cs | 106 +++++++++++++----- .../Process/Traversal/TraversalPredicate.cs | 85 -------------- .../src/Gremlin.Net/Process/Traversal/__.cs | 20 ++-- .../Structure/IO/GraphSON/GraphSONWriter.cs | 2 +- ...lPredicateSerializer.cs => PSerializer.cs} | 4 +- .../Gherkin/GherkinTestRunner.cs | 18 +-- .../Gherkin/IgnoreException.cs | 5 - ...salPredicateParameter.cs => PParameter.cs} | 20 ++-- .../TraversalEvaluationTests.cs | 2 +- .../TraversalEvaluation/TraversalParser.cs | 2 +- .../BytecodeGraphSONSerializerTests.cs | 2 +- .../IO/GraphSON/GraphSONWriterTests.cs | 4 +- 16 files changed, 183 insertions(+), 172 deletions(-) delete mode 100644 gremlin-dotnet/src/Gremlin.Net/Process/Traversal/TraversalPredicate.cs rename gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/{TraversalPredicateSerializer.cs => PSerializer.cs} (92%) rename gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/{TraversalPredicateParameter.cs => PParameter.cs} (80%) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 58c4dd0c6ea..97b90a56de8 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -43,6 +43,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima * Fixed a bug in Gremlin Console which prevented handling of `gremlin.sh` flags that had an "=" between the flag and its arguments. * Fixed bug where `SparkMessenger` was not applying the `edgeFunction` from `MessageScope`. * Fixed a bug in `ComputerAwareStep` that didn't handle `reset()` properly and thus occasionally produced some extra traversers. +* Removed `TraversalPredicate` class in Gremlin.Net. It is now included in the `P` class instead. [[release-3-2-7]] === TinkerPop 3.2.7 (Release Date: December 17, 2017) diff --git a/gremlin-dotnet/glv/P.template b/gremlin-dotnet/glv/P.template index f33712786a6..ad037c15467 100644 --- a/gremlin-dotnet/glv/P.template +++ b/gremlin-dotnet/glv/P.template @@ -30,20 +30,72 @@ namespace Gremlin.Net.Process.Traversal /// A is a predicate of the form Func<object, bool>. /// That is, given some object, return true or false. /// - public class P + public class P : IPredicate { + /// + /// Initializes a new instance of the class. + /// + /// The name of the predicate. + /// The value of the predicate. + /// An optional other predicate that is used as an argument for this predicate. + public P(string operatorName, dynamic value, P other = null) + { + OperatorName = operatorName; + Value = value; + Other = other; + } + + /// + /// Gets the name of the predicate. + /// + public string OperatorName { get; } + + /// + /// Gets the value of the predicate. + /// + public dynamic Value { get; } + + /// + /// Gets an optional other predicate that is used as an argument for this predicate. + /// + public P Other { get; } + + /// + /// Returns a composed predicate that represents a logical AND of this predicate and another. + /// + /// A predicate that will be logically-ANDed with this predicate. + /// The composed predicate. + public P And(P otherPredicate) + { + return new P("and", this, otherPredicate); + } + + /// + /// Returns a composed predicate that represents a logical OR of this predicate and another. + /// + /// A predicate that will be logically-ORed with this predicate. + /// The composed predicate. + public P Or(P otherPredicate) + { + return new P("or", this, otherPredicate); + } <% pmethods.findAll{ !(it in ["within", "without"]) }.each { method -> %> - public static TraversalPredicate <%= toCSharpMethodName.call(method) %>(params object[] args) + public static P <%= toCSharpMethodName.call(method) %>(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("<%= method %>", value); + return new P("<%= method %>", value); } <% } %><% pmethods.findAll{ it in ["within", "without"] }.each { method -> %> - public static TraversalPredicate <%= toCSharpMethodName.call(method) %>(params object[] args) + public static P <%= toCSharpMethodName.call(method) %>(params object[] args) { - return new TraversalPredicate("<%= method %>", args); + return new P("<%= method %>", args); } <% } %> + /// + public override string ToString() + { + return Other == null ? \$"{OperatorName}({Value})" : \$"{OperatorName}({Value},{Other})"; + } } #pragma warning restore 1591 diff --git a/gremlin-dotnet/glv/generate.groovy b/gremlin-dotnet/glv/generate.groovy index 040430754a0..5057ff81111 100644 --- a/gremlin-dotnet/glv/generate.groovy +++ b/gremlin-dotnet/glv/generate.groovy @@ -49,7 +49,7 @@ def toCSharpTypeMap = ["Long": "long", "Traversal": "ITraversal", "Traversal[]": "ITraversal[]", "Predicate": "IPredicate", - "P": "TraversalPredicate", + "P": "P", "TraversalStrategy": "ITraversalStrategy", "TraversalStrategy[]": "ITraversalStrategy[]", "Function": "IFunction", diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs index 7100ea36f47..c8708dfd8e8 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs @@ -667,7 +667,7 @@ public GraphTraversal Has (string propertyKey, object value) /// /// Adds the has step to this . /// - public GraphTraversal Has (string propertyKey, TraversalPredicate predicate) + public GraphTraversal Has (string propertyKey, P predicate) { Bytecode.AddStep("has", propertyKey, predicate); return Wrap(this); @@ -685,7 +685,7 @@ public GraphTraversal Has (string label, string propertyKey, object value) /// /// Adds the has step to this . /// - public GraphTraversal Has (string label, string propertyKey, TraversalPredicate predicate) + public GraphTraversal Has (string label, string propertyKey, P predicate) { Bytecode.AddStep("has", label, propertyKey, predicate); return Wrap(this); @@ -712,7 +712,7 @@ public GraphTraversal Has (T accessor, object value) /// /// Adds the has step to this . /// - public GraphTraversal Has (T accessor, TraversalPredicate predicate) + public GraphTraversal Has (T accessor, P predicate) { Bytecode.AddStep("has", accessor, predicate); return Wrap(this); @@ -741,7 +741,7 @@ public GraphTraversal HasId (object id, params object[] otherIds) /// /// Adds the hasId step to this . /// - public GraphTraversal HasId (TraversalPredicate predicate) + public GraphTraversal HasId (P predicate) { Bytecode.AddStep("hasId", predicate); return Wrap(this); @@ -750,7 +750,7 @@ public GraphTraversal HasId (TraversalPredicate predicate) /// /// Adds the hasKey step to this . /// - public GraphTraversal HasKey (TraversalPredicate predicate) + public GraphTraversal HasKey (P predicate) { Bytecode.AddStep("hasKey", predicate); return Wrap(this); @@ -770,7 +770,7 @@ public GraphTraversal HasKey (string label, params string[] otherLabels) /// /// Adds the hasLabel step to this . /// - public GraphTraversal HasLabel (TraversalPredicate predicate) + public GraphTraversal HasLabel (P predicate) { Bytecode.AddStep("hasLabel", predicate); return Wrap(this); @@ -810,7 +810,7 @@ public GraphTraversal HasValue (object value, params object[] otherValues) /// /// Adds the hasValue step to this . /// - public GraphTraversal HasValue (TraversalPredicate predicate) + public GraphTraversal HasValue (P predicate) { Bytecode.AddStep("hasValue", predicate); return Wrap(this); @@ -888,7 +888,7 @@ public GraphTraversal Is (object value) /// /// Adds the is step to this . /// - public GraphTraversal Is (TraversalPredicate predicate) + public GraphTraversal Is (P predicate) { Bytecode.AddStep("is", predicate); return Wrap(this); @@ -1660,7 +1660,7 @@ public GraphTraversal Values (params string[] propertyKeys) /// /// Adds the where step to this . /// - public GraphTraversal Where (TraversalPredicate predicate) + public GraphTraversal Where (P predicate) { Bytecode.AddStep("where", predicate); return Wrap(this); @@ -1669,7 +1669,7 @@ public GraphTraversal Where (TraversalPredicate predicate) /// /// Adds the where step to this . /// - public GraphTraversal Where (string startKey, TraversalPredicate predicate) + public GraphTraversal Where (string startKey, P predicate) { Bytecode.AddStep("where", startKey, predicate); return Wrap(this); diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/P.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/P.cs index 0a7809fa6d5..e3a1e7690ac 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/P.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/P.cs @@ -30,85 +30,137 @@ namespace Gremlin.Net.Process.Traversal /// A is a predicate of the form Func<object, bool>. /// That is, given some object, return true or false. /// - public class P + public class P : IPredicate { + /// + /// Initializes a new instance of the class. + /// + /// The name of the predicate. + /// The value of the predicate. + /// An optional other predicate that is used as an argument for this predicate. + public P(string operatorName, dynamic value, P other = null) + { + OperatorName = operatorName; + Value = value; + Other = other; + } + + /// + /// Gets the name of the predicate. + /// + public string OperatorName { get; } + + /// + /// Gets the value of the predicate. + /// + public dynamic Value { get; } + + /// + /// Gets an optional other predicate that is used as an argument for this predicate. + /// + public P Other { get; } + + /// + /// Returns a composed predicate that represents a logical AND of this predicate and another. + /// + /// A predicate that will be logically-ANDed with this predicate. + /// The composed predicate. + public P And(P otherPredicate) + { + return new P("and", this, otherPredicate); + } - public static TraversalPredicate Between(params object[] args) + /// + /// Returns a composed predicate that represents a logical OR of this predicate and another. + /// + /// A predicate that will be logically-ORed with this predicate. + /// The composed predicate. + public P Or(P otherPredicate) + { + return new P("or", this, otherPredicate); + } + + public static P Between(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("between", value); + return new P("between", value); } - public static TraversalPredicate Eq(params object[] args) + public static P Eq(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("eq", value); + return new P("eq", value); } - public static TraversalPredicate Gt(params object[] args) + public static P Gt(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("gt", value); + return new P("gt", value); } - public static TraversalPredicate Gte(params object[] args) + public static P Gte(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("gte", value); + return new P("gte", value); } - public static TraversalPredicate Inside(params object[] args) + public static P Inside(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("inside", value); + return new P("inside", value); } - public static TraversalPredicate Lt(params object[] args) + public static P Lt(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("lt", value); + return new P("lt", value); } - public static TraversalPredicate Lte(params object[] args) + public static P Lte(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("lte", value); + return new P("lte", value); } - public static TraversalPredicate Neq(params object[] args) + public static P Neq(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("neq", value); + return new P("neq", value); } - public static TraversalPredicate Not(params object[] args) + public static P Not(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("not", value); + return new P("not", value); } - public static TraversalPredicate Outside(params object[] args) + public static P Outside(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("outside", value); + return new P("outside", value); } - public static TraversalPredicate Test(params object[] args) + public static P Test(params object[] args) { var value = args.Length == 1 ? args[0] : args; - return new TraversalPredicate("test", value); + return new P("test", value); } - public static TraversalPredicate Within(params object[] args) + public static P Within(params object[] args) { - return new TraversalPredicate("within", args); + return new P("within", args); } - public static TraversalPredicate Without(params object[] args) + public static P Without(params object[] args) { - return new TraversalPredicate("without", args); + return new P("without", args); } + /// + public override string ToString() + { + return Other == null ? $"{OperatorName}({Value})" : $"{OperatorName}({Value},{Other})"; + } } #pragma warning restore 1591 diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/TraversalPredicate.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/TraversalPredicate.cs deleted file mode 100644 index e8b5be8e647..00000000000 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/TraversalPredicate.cs +++ /dev/null @@ -1,85 +0,0 @@ -#region License - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#endregion - -namespace Gremlin.Net.Process.Traversal -{ - /// - /// Represents a predicate (boolean-valued function) used in a . - /// - public class TraversalPredicate : IPredicate - { - /// - /// Initializes a new instance of the class. - /// - /// The name of the predicate. - /// The value of the predicate. - /// An optional other predicate that is used as an argument for this predicate. - public TraversalPredicate(string operatorName, dynamic value, TraversalPredicate other = null) - { - OperatorName = operatorName; - Value = value; - Other = other; - } - - /// - /// Gets the name of the predicate. - /// - public string OperatorName { get; } - - /// - /// Gets the value of the predicate. - /// - public dynamic Value { get; } - - /// - /// Gets an optional other predicate that is used as an argument for this predicate. - /// - public TraversalPredicate Other { get; } - - /// - /// Returns a composed predicate that represents a logical AND of this predicate and another. - /// - /// A predicate that will be logically-ANDed with this predicate. - /// The composed predicate. - public TraversalPredicate And(TraversalPredicate otherPredicate) - { - return new TraversalPredicate("and", this, otherPredicate); - } - - /// - /// Returns a composed predicate that represents a logical OR of this predicate and another. - /// - /// A predicate that will be logically-ORed with this predicate. - /// The composed predicate. - public TraversalPredicate Or(TraversalPredicate otherPredicate) - { - return new TraversalPredicate("or", this, otherPredicate); - } - - /// - public override string ToString() - { - return Other == null ? $"{OperatorName}({Value})" : $"{OperatorName}({Value},{Other})"; - } - } -} \ No newline at end of file diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs index 9620e7fb0c8..46f510af462 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs @@ -485,7 +485,7 @@ public static GraphTraversal Has(string propertyKey, object valu /// /// Spawns a and adds the has step to that traversal. /// - public static GraphTraversal Has(string propertyKey, TraversalPredicate predicate) + public static GraphTraversal Has(string propertyKey, P predicate) { return new GraphTraversal().Has(propertyKey, predicate); } @@ -501,7 +501,7 @@ public static GraphTraversal Has(string label, string propertyKe /// /// Spawns a and adds the has step to that traversal. /// - public static GraphTraversal Has(string label, string propertyKey, TraversalPredicate predicate) + public static GraphTraversal Has(string label, string propertyKey, P predicate) { return new GraphTraversal().Has(label, propertyKey, predicate); } @@ -525,7 +525,7 @@ public static GraphTraversal Has(T accessor, object value) /// /// Spawns a and adds the has step to that traversal. /// - public static GraphTraversal Has(T accessor, TraversalPredicate predicate) + public static GraphTraversal Has(T accessor, P predicate) { return new GraphTraversal().Has(accessor, predicate); } @@ -551,7 +551,7 @@ public static GraphTraversal HasId(object id, params object[] ot /// /// Spawns a and adds the hasId step to that traversal. /// - public static GraphTraversal HasId(TraversalPredicate predicate) + public static GraphTraversal HasId(P predicate) { return new GraphTraversal().HasId(predicate); } @@ -559,7 +559,7 @@ public static GraphTraversal HasId(TraversalPredicate predicate) /// /// Spawns a and adds the hasKey step to that traversal. /// - public static GraphTraversal HasKey(TraversalPredicate predicate) + public static GraphTraversal HasKey(P predicate) { return new GraphTraversal().HasKey(predicate); } @@ -577,7 +577,7 @@ public static GraphTraversal HasKey(string label, params string[ /// /// Spawns a and adds the hasLabel step to that traversal. /// - public static GraphTraversal HasLabel(TraversalPredicate predicate) + public static GraphTraversal HasLabel(P predicate) { return new GraphTraversal().HasLabel(predicate); } @@ -613,7 +613,7 @@ public static GraphTraversal HasValue(object value, params objec /// /// Spawns a and adds the hasValue step to that traversal. /// - public static GraphTraversal HasValue(TraversalPredicate predicate) + public static GraphTraversal HasValue(P predicate) { return new GraphTraversal().HasValue(predicate); } @@ -683,7 +683,7 @@ public static GraphTraversal Is(object value) /// /// Spawns a and adds the is step to that traversal. /// - public static GraphTraversal Is(TraversalPredicate predicate) + public static GraphTraversal Is(P predicate) { return new GraphTraversal().Is(predicate); } @@ -1293,7 +1293,7 @@ public static GraphTraversal Values(params string[] propertyKeys /// /// Spawns a and adds the where step to that traversal. /// - public static GraphTraversal Where(TraversalPredicate predicate) + public static GraphTraversal Where(P predicate) { return new GraphTraversal().Where(predicate); } @@ -1301,7 +1301,7 @@ public static GraphTraversal Where(TraversalPredicate predicate) /// /// Spawns a and adds the where step to that traversal. /// - public static GraphTraversal Where(string startKey, TraversalPredicate predicate) + public static GraphTraversal Where(string startKey, P predicate) { return new GraphTraversal().Where(startKey, predicate); } diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs index d5b7acce5ba..f23d80debcb 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs @@ -54,7 +54,7 @@ public class GraphSONWriter {typeof(DateTimeOffset), new DateSerializer()}, {typeof(Type), new ClassSerializer()}, {typeof(EnumWrapper), new EnumSerializer()}, - {typeof(TraversalPredicate), new TraversalPredicateSerializer()}, + {typeof(P), new PSerializer()}, {typeof(Vertex), new VertexSerializer()}, {typeof(Edge), new EdgeSerializer()}, {typeof(Property), new PropertySerializer()}, diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PSerializer.cs similarity index 92% rename from gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs rename to gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PSerializer.cs index 937cb906117..46facda8a9d 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PSerializer.cs @@ -26,11 +26,11 @@ namespace Gremlin.Net.Structure.IO.GraphSON { - internal class TraversalPredicateSerializer : IGraphSONSerializer + internal class PSerializer : IGraphSONSerializer { public Dictionary Dictify(dynamic predicate, GraphSONWriter writer) { - TraversalPredicate p = predicate; + P p = predicate; var value = p.Other == null ? writer.ToDict(p.Value) : new List {writer.ToDict(p.Value), writer.ToDict(p.Other)}; diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs index d906357fd48..c3819fedede 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs @@ -43,23 +43,15 @@ public class GherkinTestRunner {"g_V_hasIdXwithinXemptyXX_count", IgnoreReason.PWithinWrapsArgumentsInArray}, {"g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX", IgnoreReason.PWithinWrapsArgumentsInArray}, { - "g_V_hasLabelXpersonX_hasXage_notXlteX10X_andXnotXbetweenX11_20XXXX_andXltX29X_orXeqX35XXXX_name", - IgnoreReason.PNotCreatedCorrectlyByGherkinRunner - }, - { - "g_V_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_bothXknowsX_bothXknowsX_asXdX_whereXc__notXeqXaX_orXeqXdXXXX_selectXa_b_c_dX", - IgnoreReason.PNotCreatedCorrectlyByGherkinRunner - }, - { - "g_V_asXaX_outEXcreatedX_asXbX_inV_asXcX_whereXa_gtXbX_orXeqXbXXX_byXageX_byXweightX_byXweightX_selectXa_cX_byXnameX", - IgnoreReason.PNotCreatedCorrectlyByGherkinRunner + "g_V_asXaX_out_asXbX_whereXandXasXaX_outXknowsX_asXbX__orXasXbX_outXcreatedX_hasXname_rippleX__asXbX_inXknowsX_count_isXnotXeqX0XXXXX_selectXa_bX", + IgnoreReason.PNotDeserializationProblem }, { - "g_V_asXaX_outEXcreatedX_asXbX_inV_asXcX_inXcreatedX_asXdX_whereXa_ltXbX_orXgtXcXX_andXneqXdXXX_byXageX_byXweightX_byXinXcreatedX_valuesXageX_minX_selectXa_c_dX", - IgnoreReason.PNotCreatedCorrectlyByGherkinRunner + "g_V_hasLabelXpersonX_hasXage_notXlteX10X_andXnotXbetweenX11_20XXXX_andXltX29X_orXeqX35XXXX_name", + IgnoreReason.PNotDeserializationProblem }, { - "g_V_asXaX_out_asXbX_whereXandXasXaX_outXknowsX_asXbX__orXasXbX_outXcreatedX_hasXname_rippleX__asXbX_inXknowsX_count_isXnotXeqX0XXXXX_selectXa_bX", + "g_V_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_bothXknowsX_bothXknowsX_asXdX_whereXc__notXeqXaX_orXeqXdXXXX_selectXa_b_c_dX", IgnoreReason.PNotDeserializationProblem } }; diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs index dae2cedbea4..fd226bf8f40 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs @@ -43,10 +43,6 @@ private static string GetMessage(IgnoreReason reason) case IgnoreReason.LambdaNotSupported: reasonSuffix = " because lambdas are not supported in Gremlin.NET (TINKERPOP-1854)"; break; - case IgnoreReason.PNotCreatedCorrectlyByGherkinRunner: - reasonSuffix = - " because the Gherkin runner can't call methods in TraversalPredicate class (TINKERPOP-1919)"; - break; case IgnoreReason.PWithinWrapsArgumentsInArray: reasonSuffix = " because P.Within() arguments are incorrectly wrapped in an array (TINKERPOP-1920)"; break; @@ -61,7 +57,6 @@ private static string GetMessage(IgnoreReason reason) public enum IgnoreReason { LambdaNotSupported, - PNotCreatedCorrectlyByGherkinRunner, PWithinWrapsArgumentsInArray, PNotDeserializationProblem } diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/PParameter.cs similarity index 80% rename from gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs rename to gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/PParameter.cs index 57262c12ed6..b25faef6a06 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/PParameter.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; +using System.Dynamic; using System.Linq; using System.Reflection; using Gremlin.Net.Process.Traversal; @@ -32,17 +33,17 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation /// /// Represents a parameter for a traversal predicate (ie: P.gt()) /// - internal class TraversalPredicateParameter : ITokenParameter, IEquatable + internal class PParameter : ITokenParameter, IEquatable { private IDictionary _contextParameterValues; public IList Tokens { get; } - public TraversalPredicateParameter(IList tokens) + public PParameter(IList tokens) { Tokens = tokens; } - public bool Equals(TraversalPredicateParameter other) + public bool Equals(PParameter other) { return Tokens.SequenceEqual(other.Tokens); } @@ -52,7 +53,7 @@ public override bool Equals(object obj) if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; - return Equals((TraversalPredicateParameter) obj); + return Equals((PParameter) obj); } public override int GetHashCode() @@ -69,20 +70,23 @@ public object GetValue() var token = Tokens[i]; token.SetContextParameterValues(_contextParameterValues); var method = type.GetMethod(TraversalParser.GetCsharpName(token.Name), - BindingFlags.Static | BindingFlags.Public); + BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); if (method == null) { throw new InvalidOperationException($"Predicate (P) method '{token}' not found for testing"); } - instance = method.Invoke(instance, - new object[] {token.Parameters.Select(p => p.GetValue()).ToArray()}); + + var parameters = method.IsStatic + ? new object[] {token.Parameters.Select(p => p.GetValue()).ToArray()} + : token.Parameters.Select(p => p.GetValue()).ToArray(); + instance = method.Invoke(instance, parameters); } return instance; } public Type GetParameterType() { - return typeof(TraversalPredicate); + return typeof(P); } public void SetContextParameterValues(IDictionary parameterValues) diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs index 94a8c993bc1..4e2bfff96fa 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs @@ -55,7 +55,7 @@ public void Traversal_Parser_Should_Parse_Into_Tokens() new[] {new Token("__"), new Token("in", new StringParameter("knows"))}, "__.in(\"knows\")")})}), Tuple.Create("g.V().has(\"age\",P.gt(27))", new[] {new Token("has", new ITokenParameter[] { new StringParameter("age"), - new TraversalPredicateParameter( + new PParameter( new[] { new Token("P"), new Token("gt", LiteralParameter.Create(27)) }) })}), Tuple.Create("g.V().count(Scope.local)", new[] { new Token("count", new TraversalEnumParameter("Scope.local"))}), diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs index 118fceaa3dd..11145dae69f 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs @@ -406,7 +406,7 @@ private static ITokenParameter ParseParameter(string text, ref int i) } if (text.Substring(i, 2).StartsWith("P.")) { - return new TraversalPredicateParameter(ParseTokens(text, ref i)); + return new PParameter(ParseTokens(text, ref i)); } var parameterText = text.Substring(i, text.IndexOf(')', i) - i); var separatorIndex = parameterText.IndexOf(','); diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs index 8ed7a3d4657..568b97021fe 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/BytecodeGraphSONSerializerTests.cs @@ -118,7 +118,7 @@ public void ShouldSerializeBytecodeWithSourcesStep() bytecode.AddSource("withSideEffect", "a", new List {"josh", "peter"}); bytecode.AddStep("V", 1); bytecode.AddStep("values", "name"); - bytecode.AddStep("where", new TraversalPredicate("within", "a")); + bytecode.AddStep("where", new P("within", "a")); var graphsonWriter = CreateGraphSONWriter(); var graphSON = graphsonWriter.WriteObject(bytecode); diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs index 3d0253353b1..3e2d307fbad 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs @@ -222,7 +222,7 @@ public void ShouldSerializeList() public void ShouldSerializePredicateWithTwoValues() { var writer = CreateStandardGraphSONWriter(); - var predicate = new TraversalPredicate("within", new List {1, 2}); + var predicate = new P("within", new List {1, 2}); var serializedPredicate = writer.WriteObject(predicate); @@ -235,7 +235,7 @@ public void ShouldSerializePredicateWithTwoValues() public void ShouldSerializePredicateWithSingleValue() { var writer = CreateStandardGraphSONWriter(); - var predicate = new TraversalPredicate("lt", 5); + var predicate = new P("lt", 5); var serializedPredicate = writer.WriteObject(predicate); From 5cf1cba59cfb6818b371b1d605dac3b8d190157a Mon Sep 17 00:00:00 2001 From: Florian Hockmann Date: Tue, 13 Mar 2018 23:39:21 +0100 Subject: [PATCH 2/2] TINKERPOP-1919 Add note about merged P classes to upgrade docs --- docs/src/upgrade/release-3.2.x-incubating.asciidoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc index 0cb8ddc10af..08488430914 100644 --- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc +++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc @@ -53,6 +53,18 @@ However, usage of these tokens themselves shouldn't change at all (e.g. `T.Id` i See: link:https://issues.apache.org/jira/browse/TINKERPOP-1901[TINKERPOP-1901] +==== Gremlin.Net: Traversal Predicate Classes Merged + +Gremlin.Net used two classes for traversal predicates: `P` and `TraversalPredicate`. Steps that worked with traversal +predicates expected objects of type `TraversalPredicate`, but they were constructed from the `P` class +(e.g. `P.Gt(1)` returned a `TraversalPredicate`). Merging these two classes into the `P` class should avoid unnecessary +confusion. Most users should not notice this change as predicates can still be constructed exactly as before, e.g., +`P.Gt(1).And(P.Lt(3))` still works without any modifications. +Only users that implemented their own predicates and used `TraversalPredicate` as the base class need to change their +implementation to now use `P` as the new base class. + +See: link:https://issues.apache.org/jira/browse/TINKERPOP-1919[TINKERPOP-1919] + === Upgrading for Providers ==== Graph System Providers