This is an automated email from the ASF dual-hosted git repository. florianhockmann pushed a commit to branch TINKERPOP-2605 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 59f951d5a2a5555223a398aac66c7895c474071d Author: Florian Hockmann <[email protected]> AuthorDate: Wed Mar 2 16:55:14 2022 +0100 TINKERPOP-2605 Improve handling of null arguments `GraphTraversal`/`GraphTraversalSource`: Ensure that no `NullReferenceException` gets thrown. Either allow `null` as an argument or throw an `ArgumentNullException` if it doesn't seem sensible and if Java also doesn't allow `null`. __: Simply forward all `null` arguments to the steps in `GraphTraversal` so they can be handled there and we don't need to duplicate the logic whether we want to allow `null` or throw. I had to adapt the `DotNetTranslator` a bit as the logic to avoid problems where multiple overloads would be possible was to eager. This resulted in a `params object[]` argument that should be set to `null` for a scenarios, being actually tested with an object[] which had `null` as an element. This let the scenarios pass although users would get a `NullReferenceException` since they probably won't add the unnecessary `object` cast. Example: `HasKey('name', null)` -> threw a `NullReferenceException` `HasKey('name', (object) null)` -> passed --- .../traversal/translator/DotNetTranslator.java | 6 +- .../traversal/translator/DotNetTranslatorTest.java | 6 +- .../Process/Traversal/GraphTraversal.cs | 179 ++++++++++++++++----- .../Process/Traversal/GraphTraversalSource.cs | 31 ++-- .../src/Gremlin.Net/Process/Traversal/__.cs | 68 ++++---- .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 14 +- .../BytecodeGeneration/BytecodeGenerationTests.cs | 17 ++ 7 files changed, 216 insertions(+), 105 deletions(-) diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java index d2d9c80..a1388eb 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslator.java @@ -391,10 +391,10 @@ public final class DotNetTranslator implements Translator.ScriptTranslator { // them i guess if (null == instArg) { if ((methodName.equals(GraphTraversal.Symbols.addV) && idx % 2 == 0) || - methodName.equals(GraphTraversal.Symbols.hasLabel)|| - methodName.equals(GraphTraversal.Symbols.hasKey)) { + (methodName.equals(GraphTraversal.Symbols.hasLabel) && instArgs.length == 1 && idx == 0) || + (methodName.equals(GraphTraversal.Symbols.hasKey) && instArgs.length == 1 && idx == 0)) { script.append("(string) "); - } else if (methodName.equals(GraphTraversal.Symbols.hasValue)) { + } else if (methodName.equals(GraphTraversal.Symbols.hasValue) && idx == 0) { script.append("(object) "); } else if (methodName.equals(GraphTraversal.Symbols.has)) { if (instArgs.length == 2) { diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java index 000d224..87aea7a 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/DotNetTranslatorTest.java @@ -175,11 +175,11 @@ public class DotNetTranslatorTest { String script = translator.translate(g.V().hasLabel(null).asAdmin().getBytecode()).getScript(); assertEquals("g.V().HasLabel((string) null)", script); script = translator.translate(g.V().hasLabel(null, null).asAdmin().getBytecode()).getScript(); - assertEquals("g.V().HasLabel((string) null,(string) null)", script); + assertEquals("g.V().HasLabel(null,null)", script); script = translator.translate(g.V().hasLabel(null, "person").asAdmin().getBytecode()).getScript(); - assertEquals("g.V().HasLabel((string) null,\"person\")", script); + assertEquals("g.V().HasLabel(null,\"person\")", script); script = translator.translate(g.V().hasLabel(null, "person", null).asAdmin().getBytecode()).getScript(); - assertEquals("g.V().HasLabel((string) null,\"person\",(string) null)", script); + assertEquals("g.V().HasLabel(null,\"person\",null)", script); script = translator.translate(g.V().has(T.label, (Object) null).asAdmin().getBytecode()).getScript(); assertEquals("g.V().Has(T.Label,(object) null)", script); } diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs index a916625..b6297d9 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs @@ -21,8 +21,8 @@ #endregion +using System; using System.Collections.Generic; -using System.Linq; using Gremlin.Net.Structure; namespace Gremlin.Net.Process.Traversal @@ -79,16 +79,16 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Vertex> V (params object[] vertexIdsOrElements) { - var args = null == vertexIdsOrElements ? new List<object>(1) {} : new List<object>(0 + vertexIdsOrElements.Length) {}; - if (null == vertexIdsOrElements) + if (vertexIdsOrElements == null) { - args.Add(null); + Bytecode.AddStep("V", new object[] { null }); } else { + var args = new List<object>(vertexIdsOrElements.Length); args.AddRange(vertexIdsOrElements); + Bytecode.AddStep("V", args.ToArray()); } - Bytecode.AddStep("V", args.ToArray()); return Wrap<S, Vertex>(this); } @@ -160,7 +160,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> And (params ITraversal[] andTraversals) { - var args = new List<object>(0 + andTraversals.Length) {}; + if (andTraversals == null) throw new ArgumentNullException(nameof(andTraversals)); + + var args = new List<object>(andTraversals.Length); args.AddRange(andTraversals); Bytecode.AddStep("and", args.ToArray()); return Wrap<S, E>(this); @@ -171,6 +173,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> As (string stepLabel, params string[] stepLabels) { + if (stepLabel == null) throw new ArgumentNullException(nameof(stepLabel)); + if (stepLabels == null) throw new ArgumentNullException(nameof(stepLabels)); + var args = new List<object>(1 + stepLabels.Length) {stepLabel}; args.AddRange(stepLabels); Bytecode.AddStep("as", args.ToArray()); @@ -209,7 +214,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Vertex> Both (params string[] edgeLabels) { - var args = new List<object>(0 + edgeLabels.Length) {}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(edgeLabels.Length); args.AddRange(edgeLabels); Bytecode.AddStep("both", args.ToArray()); return Wrap<S, Vertex>(this); @@ -220,7 +227,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Edge> BothE (params string[] edgeLabels) { - var args = new List<object>(0 + edgeLabels.Length) {}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(edgeLabels.Length); args.AddRange(edgeLabels); Bytecode.AddStep("bothE", args.ToArray()); return Wrap<S, Edge>(this); @@ -348,7 +357,10 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E2> Cap<E2> (string sideEffectKey, params string[] sideEffectKeys) { - var args = new List<object>(1 + sideEffectKeys.Length) {sideEffectKey}; + if (sideEffectKey == null) throw new ArgumentNullException(nameof(sideEffectKey)); + if (sideEffectKeys == null) throw new ArgumentNullException(nameof(sideEffectKeys)); + + var args = new List<object>(1 + sideEffectKeys.Length) { sideEffectKey }; args.AddRange(sideEffectKeys); Bytecode.AddStep("cap", args.ToArray()); return Wrap<S, E2>(this); @@ -413,7 +425,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E2> Coalesce<E2> (params ITraversal[] coalesceTraversals) { - var args = new List<object>(0 + coalesceTraversals.Length) {}; + if (coalesceTraversals == null) throw new ArgumentNullException(nameof(coalesceTraversals)); + + var args = new List<object>(coalesceTraversals.Length); args.AddRange(coalesceTraversals); Bytecode.AddStep("coalesce", args.ToArray()); return Wrap<S, E2>(this); @@ -478,7 +492,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> Dedup (Scope scope, params string[] dedupLabels) { - var args = new List<object>(1 + dedupLabels.Length) {scope}; + if (dedupLabels == null) throw new ArgumentNullException(nameof(dedupLabels)); + + var args = new List<object>(1 + dedupLabels.Length) { scope }; args.AddRange(dedupLabels); Bytecode.AddStep("dedup", args.ToArray()); return Wrap<S, E>(this); @@ -489,7 +505,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> Dedup (params string[] dedupLabels) { - var args = new List<object>(0 + dedupLabels.Length) {}; + if (dedupLabels == null) throw new ArgumentNullException(nameof(dedupLabels)); + + var args = new List<object>(dedupLabels.Length); args.AddRange(dedupLabels); Bytecode.AddStep("dedup", args.ToArray()); return Wrap<S, E>(this); @@ -509,7 +527,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, IDictionary<object, E2>> ElementMap<E2> (params string[] propertyKeys) { - var args = new List<object>(0 + propertyKeys.Length) {}; + if (propertyKeys == null) throw new ArgumentNullException(nameof(propertyKeys)); + + var args = new List<object>(0 + propertyKeys.Length); args.AddRange(propertyKeys); Bytecode.AddStep("elementMap", args.ToArray()); return Wrap<S, IDictionary<object, E2>>(this); @@ -809,8 +829,16 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> HasKey (string label, params string[] otherLabels) { - var args = new List<object>(1 + otherLabels.Length) {label}; - args.AddRange(otherLabels); + List<object> args; + if (otherLabels == null) + { + args = new List<object> { label, null }; + } + else + { + args = new List<object>(1 + otherLabels.Length) { label }; + args.AddRange(otherLabels); + } Bytecode.AddStep("hasKey", args.ToArray()); return Wrap<S, E>(this); } @@ -829,8 +857,16 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> HasLabel (string label, params string[] otherLabels) { - var args = new List<object>(1 + otherLabels.Length) {label}; - args.AddRange(otherLabels); + List<object> args; + if (otherLabels == null) + { + args = new List<object> { label, null }; + } + else + { + args = new List<object>(1 + otherLabels.Length) { label }; + args.AddRange(otherLabels); + } Bytecode.AddStep("hasLabel", args.ToArray()); return Wrap<S, E>(this); } @@ -849,8 +885,16 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> HasValue (object value, params object[] otherValues) { - var args = new List<object>(1 + otherValues.Length) {value}; - args.AddRange(otherValues); + List<object> args; + if (otherValues == null) + { + args = new List<object> { value, null }; + } + else + { + args = new List<object>(1 + otherValues.Length) { value }; + args.AddRange(otherValues); + } Bytecode.AddStep("hasValue", args.ToArray()); return Wrap<S, E>(this); } @@ -887,7 +931,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Vertex> In (params string[] edgeLabels) { - var args = new List<object>(0 + edgeLabels.Length) {}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(edgeLabels.Length); args.AddRange(edgeLabels); Bytecode.AddStep("in", args.ToArray()); return Wrap<S, Vertex>(this); @@ -898,7 +944,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Edge> InE (params string[] edgeLabels) { - var args = new List<object>(0 + edgeLabels.Length) {}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(edgeLabels.Length); args.AddRange(edgeLabels); Bytecode.AddStep("inE", args.ToArray()); return Wrap<S, Edge>(this); @@ -930,12 +978,12 @@ namespace Gremlin.Net.Process.Traversal // null injections is treated as g.inject(null) meaning inject a single null traverser if (injections == null) { - Bytecode.AddStep("inject", new object[1] { null }); + Bytecode.AddStep("inject", new object[] { null }); } else { - var args = new List<object>(0 + injections.Length) {}; - args.AddRange(injections.Cast<object>()); + var args = new List<E>(injections.Length); + args.AddRange(injections); Bytecode.AddStep("inject", args.ToArray()); } @@ -1046,7 +1094,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, IDictionary<string, E2>> Match<E2> (params ITraversal[] matchTraversals) { - var args = new List<object>(0 + matchTraversals.Length) {}; + if (matchTraversals == null) throw new ArgumentNullException(nameof(matchTraversals)); + + var args = new List<object>(matchTraversals.Length); args.AddRange(matchTraversals); Bytecode.AddStep("match", args.ToArray()); return Wrap<S, IDictionary<string, E2>>(this); @@ -1229,7 +1279,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> Or (params ITraversal[] orTraversals) { - var args = new List<object>(0 + orTraversals.Length) {}; + if (orTraversals == null) throw new ArgumentNullException(nameof(orTraversals)); + + var args = new List<object>(orTraversals.Length); args.AddRange(orTraversals); Bytecode.AddStep("or", args.ToArray()); return Wrap<S, E>(this); @@ -1267,7 +1319,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Vertex> Out (params string[] edgeLabels) { - var args = new List<object>(0 + edgeLabels.Length) {}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(edgeLabels.Length); args.AddRange(edgeLabels); Bytecode.AddStep("out", args.ToArray()); return Wrap<S, Vertex>(this); @@ -1278,7 +1332,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Edge> OutE (params string[] edgeLabels) { - var args = new List<object>(0 + edgeLabels.Length) {}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(edgeLabels.Length); args.AddRange(edgeLabels); Bytecode.AddStep("outE", args.ToArray()); return Wrap<S, Edge>(this); @@ -1361,7 +1417,12 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, IDictionary<string, E2>> Project<E2> (string projectKey, params string[] otherProjectKeys) { - var args = new List<object>(1 + otherProjectKeys.Length) {projectKey}; + // Using null as a key is allowed in Java, but we cannot support it in .NET as null is not allowed as a + // Dictionary key. + if (projectKey == null) throw new ArgumentNullException(nameof(projectKey)); + if (otherProjectKeys == null) throw new ArgumentNullException(nameof(otherProjectKeys)); + + var args = new List<object>(1 + otherProjectKeys.Length) { projectKey }; args.AddRange(otherProjectKeys); Bytecode.AddStep("project", args.ToArray()); return Wrap<S, IDictionary<string, E2>>(this); @@ -1372,7 +1433,11 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E2> Properties<E2> (params string[] propertyKeys) { - var args = new List<object>(0 + propertyKeys.Length) {}; + // Using null as a key is allowed in Java, but we cannot support it in .NET as null is not allowed as a + // Dictionary key. + if (propertyKeys == null) throw new ArgumentNullException(nameof(propertyKeys)); + + var args = new List<object>(propertyKeys.Length); args.AddRange(propertyKeys); Bytecode.AddStep("properties", args.ToArray()); return Wrap<S, E2>(this); @@ -1381,9 +1446,12 @@ namespace Gremlin.Net.Process.Traversal /// <summary> /// Adds the property step to this <see cref="GraphTraversal{SType, EType}" />. /// </summary> - public GraphTraversal<S, E> Property (Cardinality cardinality, object key, object value, params object[] keyValues) + public GraphTraversal<S, E> Property(Cardinality cardinality, object key, object value, + params object[] keyValues) { - var args = new List<object>(3 + keyValues.Length) {cardinality, key, value}; + if (keyValues == null) throw new ArgumentNullException(nameof(keyValues)); + + var args = new List<object>(3 + keyValues.Length) { cardinality, key, value }; args.AddRange(keyValues); Bytecode.AddStep("property", args.ToArray()); return Wrap<S, E>(this); @@ -1394,7 +1462,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E> Property (object key, object value, params object[] keyValues) { - var args = new List<object>(2 + keyValues.Length) {key, value}; + if (keyValues == null) throw new ArgumentNullException(nameof(keyValues)); + + var args = new List<object>(2 + keyValues.Length) { key, value }; args.AddRange(keyValues); Bytecode.AddStep("property", args.ToArray()); return Wrap<S, E>(this); @@ -1405,7 +1475,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, IDictionary<string, E2>> PropertyMap<E2> (params string[] propertyKeys) { - var args = new List<object>(0 + propertyKeys.Length) {}; + if (propertyKeys == null) throw new ArgumentNullException(nameof(propertyKeys)); + + var args = new List<object>(propertyKeys.Length); args.AddRange(propertyKeys); Bytecode.AddStep("propertyMap", args.ToArray()); return Wrap<S, IDictionary<string, E2>>(this); @@ -1513,9 +1585,12 @@ namespace Gremlin.Net.Process.Traversal /// <summary> /// Adds the select step to this <see cref="GraphTraversal{SType, EType}" />. /// </summary> - public GraphTraversal<S, IDictionary<string, E2>> Select<E2> (Pop pop, string selectKey1, string selectKey2, params string[] otherSelectKeys) + public GraphTraversal<S, IDictionary<string, E2>> Select<E2>(Pop pop, string selectKey1, string selectKey2, + params string[] otherSelectKeys) { - var args = new List<object>(3 + otherSelectKeys.Length) {pop, selectKey1, selectKey2}; + if (otherSelectKeys == null) throw new ArgumentNullException(nameof(otherSelectKeys)); + + var args = new List<object>(3 + otherSelectKeys.Length) { pop, selectKey1, selectKey2 }; args.AddRange(otherSelectKeys); Bytecode.AddStep("select", args.ToArray()); return Wrap<S, IDictionary<string, E2>>(this); @@ -1542,9 +1617,12 @@ namespace Gremlin.Net.Process.Traversal /// <summary> /// Adds the select step to this <see cref="GraphTraversal{SType, EType}" />. /// </summary> - public GraphTraversal<S, IDictionary<string, E2>> Select<E2> (string selectKey1, string selectKey2, params string[] otherSelectKeys) + public GraphTraversal<S, IDictionary<string, E2>> Select<E2>(string selectKey1, string selectKey2, + params string[] otherSelectKeys) { - var args = new List<object>(2 + otherSelectKeys.Length) {selectKey1, selectKey2}; + if (otherSelectKeys == null) throw new ArgumentNullException(nameof(otherSelectKeys)); + + var args = new List<object>(2 + otherSelectKeys.Length) { selectKey1, selectKey2 }; args.AddRange(otherSelectKeys); Bytecode.AddStep("select", args.ToArray()); return Wrap<S, IDictionary<string, E2>>(this); @@ -1708,7 +1786,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Vertex> To (Direction direction, params string[] edgeLabels) { - var args = new List<object>(1 + edgeLabels.Length) {direction}; + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + + var args = new List<object>(1 + edgeLabels.Length) { direction }; args.AddRange(edgeLabels); Bytecode.AddStep("to", args.ToArray()); return Wrap<S, Vertex>(this); @@ -1746,6 +1826,8 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, Edge> ToE (Direction direction, params string[] edgeLabels) { + if (edgeLabels == null) throw new ArgumentNullException(nameof(edgeLabels)); + var args = new List<object>(1 + edgeLabels.Length) {direction}; args.AddRange(edgeLabels); Bytecode.AddStep("toE", args.ToArray()); @@ -1793,7 +1875,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E2> Union<E2> (params ITraversal[] unionTraversals) { - var args = new List<object>(0 + unionTraversals.Length) {}; + if (unionTraversals == null) throw new ArgumentNullException(nameof(unionTraversals)); + + var args = new List<object>(unionTraversals.Length); args.AddRange(unionTraversals); Bytecode.AddStep("union", args.ToArray()); return Wrap<S, E2>(this); @@ -1831,7 +1915,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, IDictionary<TKey, TValue>> ValueMap<TKey, TValue> (params string[] propertyKeys) { - var args = new List<object>(0 + propertyKeys.Length) {}; + if (propertyKeys == null) throw new ArgumentNullException(nameof(propertyKeys)); + + var args = new List<object>(propertyKeys.Length); args.AddRange(propertyKeys); Bytecode.AddStep("valueMap", args.ToArray()); return Wrap<S, IDictionary<TKey, TValue>>(this); @@ -1840,9 +1926,12 @@ namespace Gremlin.Net.Process.Traversal /// <summary> /// Adds the valueMap step to this <see cref="GraphTraversal{SType, EType}" />. /// </summary> - public GraphTraversal<S, IDictionary<TKey, TValue>> ValueMap<TKey, TValue> (bool includeTokens, params string[] propertyKeys) + public GraphTraversal<S, IDictionary<TKey, TValue>> ValueMap<TKey, TValue>(bool includeTokens, + params string[] propertyKeys) { - var args = new List<object>(1 + propertyKeys.Length) {includeTokens}; + if (propertyKeys == null) throw new ArgumentNullException(nameof(propertyKeys)); + + var args = new List<object>(1 + propertyKeys.Length) { includeTokens }; args.AddRange(propertyKeys); Bytecode.AddStep("valueMap", args.ToArray()); return Wrap<S, IDictionary<TKey, TValue>>(this); @@ -1853,7 +1942,9 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public GraphTraversal<S, E2> Values<E2> (params string[] propertyKeys) { - var args = new List<object>(0 + propertyKeys.Length) {}; + if (propertyKeys == null) throw new ArgumentNullException(nameof(propertyKeys)); + + var args = new List<object>(propertyKeys.Length); args.AddRange(propertyKeys); Bytecode.AddStep("values", args.ToArray()); return Wrap<S, E2>(this); diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs index 5ad2f7d..8cc3f4a 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs @@ -24,7 +24,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Gremlin.Net.Driver.Remote; using Gremlin.Net.Process.Remote; using Gremlin.Net.Process.Traversal.Strategy.Decoration; using Gremlin.Net.Structure; @@ -224,9 +223,11 @@ namespace Gremlin.Net.Process.Traversal public GraphTraversalSource WithStrategies(params ITraversalStrategy[] traversalStrategies) { + if (traversalStrategies == null) throw new ArgumentNullException(nameof(traversalStrategies)); + var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies), new Bytecode(Bytecode)); - var args = new List<object>(0 + traversalStrategies.Length) {}; + var args = new List<object>(traversalStrategies.Length); args.AddRange(traversalStrategies); source.Bytecode.AddSource("withStrategies", args.ToArray()); return source; @@ -234,9 +235,11 @@ namespace Gremlin.Net.Process.Traversal public GraphTraversalSource WithoutStrategies(params Type[] traversalStrategyClasses) { + if (traversalStrategyClasses == null) throw new ArgumentNullException(nameof(traversalStrategyClasses)); + var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies), new Bytecode(Bytecode)); - var args = new List<object>(0 + traversalStrategyClasses.Length) {}; + var args = new List<object>(traversalStrategyClasses.Length); args.AddRange(traversalStrategyClasses); source.Bytecode.AddSource("withoutStrategies", args.ToArray()); return source; @@ -296,16 +299,16 @@ namespace Gremlin.Net.Process.Traversal public GraphTraversal<Edge, Edge> E(params object[] edgesIds) { var traversal = new GraphTraversal<Edge, Edge>(TraversalStrategies, new Bytecode(Bytecode)); - var args = null == edgesIds ? new List<object>(1) {} : new List<object>(0 + edgesIds.Length) {}; - if (null == edgesIds) + if (edgesIds == null) { - args.Add(null); + traversal.Bytecode.AddStep("E", new object[] { null }); } else { + var args = new List<object>(edgesIds.Length); args.AddRange(edgesIds); + traversal.Bytecode.AddStep("E", args.ToArray()); } - traversal.Bytecode.AddStep("E", args.ToArray()); return traversal; } @@ -316,16 +319,16 @@ namespace Gremlin.Net.Process.Traversal public GraphTraversal<Vertex, Vertex> V(params object[] vertexIds) { var traversal = new GraphTraversal<Vertex, Vertex>(TraversalStrategies, new Bytecode(Bytecode)); - var args = null == vertexIds ? new List<object>(1) {} : new List<object>(0 + vertexIds.Length) {}; - if (null == vertexIds) + if (vertexIds == null) { - args.Add(null); + traversal.Bytecode.AddStep("V", new object[] { null }); } else { + var args = new List<object>(vertexIds.Length); args.AddRange(vertexIds); + traversal.Bytecode.AddStep("V", args.ToArray()); } - traversal.Bytecode.AddStep("V", args.ToArray()); return traversal; } @@ -439,12 +442,12 @@ namespace Gremlin.Net.Process.Traversal // null starts is treated as g.inject(null) meaning inject a single null traverser if (starts == null) { - traversal.Bytecode.AddStep("inject", new object[1] { null }); + traversal.Bytecode.AddStep("inject", new object[] { null }); } else { - var args = new List<object>(0 + starts.Length) {}; - args.AddRange(starts.Cast<object>()); + var args = new List<S>(starts.Length); + args.AddRange(starts); traversal.Bytecode.AddStep("inject", args.ToArray()); } diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs index 62c19e0..47b3158 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs @@ -44,7 +44,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Vertex> V(params object[] vertexIdsOrElements) { - return vertexIdsOrElements.Length == 0 + return vertexIdsOrElements is { Length: 0 } ? new GraphTraversal<object, Vertex>().V() : new GraphTraversal<object, Vertex>().V(vertexIdsOrElements); } @@ -110,7 +110,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> And(params ITraversal[] andTraversals) { - return andTraversals.Length == 0 + return andTraversals is { Length: 0 } ? new GraphTraversal<object, object>().And() : new GraphTraversal<object, object>().And(andTraversals); } @@ -120,7 +120,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> As(string label, params string[] labels) { - return labels.Length == 0 + return labels is { Length: 0 } ? new GraphTraversal<object, object>().As(label) : new GraphTraversal<object, object>().As(label, labels); } @@ -154,7 +154,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Vertex> Both(params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Vertex>().Both() : new GraphTraversal<object, Vertex>().Both(edgeLabels); } @@ -164,7 +164,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Edge> BothE(params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Edge>().BothE() : new GraphTraversal<object, Edge>().BothE(edgeLabels); } @@ -198,7 +198,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, E2> Cap<E2>(string sideEffectKey, params string[] sideEffectKeys) { - return sideEffectKeys.Length == 0 + return sideEffectKeys is { Length: 0 } ? new GraphTraversal<object, E2>().Cap<E2>(sideEffectKey) : new GraphTraversal<object, E2>().Cap<E2>(sideEffectKey, sideEffectKeys); } @@ -256,7 +256,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, E2> Coalesce<E2>(params ITraversal[] traversals) { - return traversals.Length == 0 + return traversals is { Length: 0 } ? new GraphTraversal<object, E2>().Coalesce<E2>() : new GraphTraversal<object, E2>().Coalesce<E2>(traversals); } @@ -306,7 +306,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> Dedup(Scope scope, params string[] dedupLabels) { - return dedupLabels.Length == 0 + return dedupLabels is { Length: 0 } ? new GraphTraversal<object, object>().Dedup(scope) : new GraphTraversal<object, object>().Dedup(scope, dedupLabels); } @@ -316,7 +316,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> Dedup(params string[] dedupLabels) { - return dedupLabels.Length == 0 + return dedupLabels is { Length: 0 } ? new GraphTraversal<object, object>().Dedup() : new GraphTraversal<object, object>().Dedup(dedupLabels); } @@ -334,7 +334,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<object, E2>> ElementMap<E2>(params string[] propertyKeys) { - return propertyKeys.Length == 0 + return propertyKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<object, E2>>().ElementMap<E2>() : new GraphTraversal<object, IDictionary<object, E2>>().ElementMap<E2>(propertyKeys); } @@ -536,7 +536,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> HasId(object id, params object[] otherIds) { - return otherIds.Length == 0 + return otherIds is { Length: 0 } ? new GraphTraversal<object, object>().HasId(id) : new GraphTraversal<object, object>().HasId(id, otherIds); } @@ -562,7 +562,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> HasKey(string label, params string[] otherLabels) { - return otherLabels.Length == 0 + return otherLabels is { Length: 0 } ? new GraphTraversal<object, object>().HasKey(label) : new GraphTraversal<object, object>().HasKey(label, otherLabels); } @@ -580,7 +580,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> HasLabel(string label, params string[] otherLabels) { - return otherLabels.Length == 0 + return otherLabels is { Length: 0 } ? new GraphTraversal<object, object>().HasLabel(label) : new GraphTraversal<object, object>().HasLabel(label, otherLabels); } @@ -598,7 +598,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> HasValue(object value, params object[] values) { - return values.Length == 0 + return values is { Length: 0 } ? new GraphTraversal<object, object>().HasValue(value) : new GraphTraversal<object, object>().HasValue(value, values); } @@ -632,7 +632,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Vertex> In(params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Vertex>().In() : new GraphTraversal<object, Vertex>().In(edgeLabels); } @@ -642,7 +642,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Edge> InE(params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Edge>().InE() : new GraphTraversal<object, Edge>().InE(edgeLabels); } @@ -668,7 +668,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> Inject(params object[] injections) { - return injections.Length == 0 + return injections is { Length: 0 } ? new GraphTraversal<object, object>().Inject() : new GraphTraversal<object, object>().Inject(injections); } @@ -766,7 +766,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<string, E2>> Match<E2>(params ITraversal[] matchTraversals) { - return matchTraversals.Length == 0 + return matchTraversals is { Length: 0 } ? new GraphTraversal<object, IDictionary<string, E2>>().Match<E2>() : new GraphTraversal<object, IDictionary<string, E2>>().Match<E2>(matchTraversals); } @@ -896,7 +896,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> Or(params ITraversal[] orTraversals) { - return orTraversals.Length == 0 + return orTraversals is { Length: 0 } ? new GraphTraversal<object, object>().Or() : new GraphTraversal<object, object>().Or(orTraversals); } @@ -930,7 +930,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Vertex> Out(params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Vertex>().Out() : new GraphTraversal<object, Vertex>().Out(edgeLabels); } @@ -940,7 +940,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Edge> OutE(params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Edge>().OutE() : new GraphTraversal<object, Edge>().OutE(edgeLabels); } @@ -966,7 +966,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<string, E2>> Project<E2>(string projectKey, params string[] projectKeys) { - return projectKeys.Length == 0 + return projectKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<string, E2>>().Project<E2>(projectKey) : new GraphTraversal<object, IDictionary<string, E2>>().Project<E2>(projectKey, projectKeys); } @@ -976,7 +976,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, E2> Properties<E2>(params string[] propertyKeys) { - return propertyKeys.Length == 0 + return propertyKeys is { Length: 0 } ? new GraphTraversal<object, E2>().Properties<E2>() : new GraphTraversal<object, E2>().Properties<E2>(propertyKeys); } @@ -986,7 +986,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> Property(Cardinality cardinality, object key, object value, params object[] keyValues) { - return keyValues.Length == 0 + return keyValues is { Length: 0 } ? new GraphTraversal<object, object>().Property(cardinality, key, value) : new GraphTraversal<object, object>().Property(cardinality, key, value, keyValues); } @@ -996,7 +996,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, object> Property(object key, object value, params object[] keyValues) { - return keyValues.Length == 0 + return keyValues is { Length: 0 } ? new GraphTraversal<object, object>().Property(key, value) : new GraphTraversal<object, object>().Property(key, value, keyValues); } @@ -1006,7 +1006,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<string, E2>> PropertyMap<E2>(params string[] propertyKeys) { - return propertyKeys.Length == 0 + return propertyKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<string, E2>>().PropertyMap<E2>() : new GraphTraversal<object, IDictionary<string, E2>>().PropertyMap<E2>(propertyKeys); } @@ -1096,7 +1096,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<string, E2>> Select<E2>(Pop pop, string selectKey1, string selectKey2, params string[] otherSelectKeys) { - return otherSelectKeys.Length == 0 + return otherSelectKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(pop, selectKey1, selectKey2) : new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(pop, selectKey1, selectKey2, otherSelectKeys); } @@ -1122,7 +1122,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<string, E2>> Select<E2>(string selectKey1, string selectKey2, params string[] otherSelectKeys) { - return otherSelectKeys.Length == 0 + return otherSelectKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(selectKey1, selectKey2) : new GraphTraversal<object, IDictionary<string, E2>>().Select<E2>(selectKey1, selectKey2, otherSelectKeys); } @@ -1260,7 +1260,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Vertex> To(Direction direction, params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Vertex>().To(direction) : new GraphTraversal<object, Vertex>().To(direction, edgeLabels); } @@ -1270,7 +1270,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, Edge> ToE(Direction direction, params string[] edgeLabels) { - return edgeLabels.Length == 0 + return edgeLabels is { Length: 0 } ? new GraphTraversal<object, Edge>().ToE(direction) : new GraphTraversal<object, Edge>().ToE(direction, edgeLabels); } @@ -1312,7 +1312,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, E2> Union<E2>(params ITraversal[] traversals) { - return traversals.Length == 0 + return traversals is { Length: 0 } ? new GraphTraversal<object, E2>().Union<E2>() : new GraphTraversal<object, E2>().Union<E2>(traversals); } @@ -1346,7 +1346,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<TKey, TValue>> ValueMap<TKey, TValue>(params string[] propertyKeys) { - return propertyKeys.Length == 0 + return propertyKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>() : new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>(propertyKeys); } @@ -1356,7 +1356,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, IDictionary<TKey, TValue>> ValueMap<TKey, TValue>(bool includeTokens, params string[] propertyKeys) { - return propertyKeys.Length == 0 + return propertyKeys is { Length: 0 } ? new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>(includeTokens) : new GraphTraversal<object, IDictionary<TKey, TValue>>().ValueMap<TKey, TValue>(includeTokens, propertyKeys); } @@ -1366,7 +1366,7 @@ namespace Gremlin.Net.Process.Traversal /// </summary> public static GraphTraversal<object, E2> Values<E2>(params string[] propertyKeys) { - return propertyKeys.Length == 0 + return propertyKeys is { Length: 0 } ? new GraphTraversal<object, E2>().Values<E2>() : new GraphTraversal<object, E2>().Values<E2>(propertyKeys); } diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs index 590cdaf..409a3b2 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs @@ -222,13 +222,13 @@ namespace Gremlin.Net.IntegrationTest.Gherkin {"g_V_hasXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has(null)}}, {"g_E_hasXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Has(null)}}, {"g_V_properties_hasKeyXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasKey((string) null)}}, - {"g_V_properties_hasKeyXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasKey((string) null,(string) null)}}, - {"g_V_properties_hasKeyXnull_ageX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasKey((string) null,"age").Value<object>()}}, + {"g_V_properties_hasKeyXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasKey(null,null)}}, + {"g_V_properties_hasKeyXnull_ageX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasKey(null,"age").Value<object>()}}, {"g_E_properties_hasKeyXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().HasKey((string) null)}}, - {"g_E_properties_hasKeyXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().HasKey((string) null,(string) null)}}, - {"g_E_properties_hasKeyXnull_weightX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().HasKey((string) null,"weight").Value<object>()}}, + {"g_E_properties_hasKeyXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().HasKey(null,null)}}, + {"g_E_properties_hasKeyXnull_weightX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().HasKey(null,"weight").Value<object>()}}, {"g_V_properties_hasValueXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasValue((object) null)}}, - {"g_V_properties_hasValueXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasValue((object) null,(object) null)}}, + {"g_V_properties_hasValueXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasValue((object) null,null)}}, {"g_V_properties_hasValueXnull_joshX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasValue((object) null,"josh").Value<object>()}}, {"g_V_hasIdXemptyX_count", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasId(p["xx1"]).Count()}}, {"g_V_hasIdXwithinXemptyXX_count", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasId(p["xx1"]).Count()}}, @@ -253,8 +253,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin {"g_V_hasLabelXpersonX_hasLabelXsoftwareX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").HasLabel("software")}}, {"g_V_hasLabelXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel((string) null)}}, {"g_V_hasXlabel_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has(T.Label,(object) null)}}, - {"g_V_hasLabelXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel((string) null,(string) null)}}, - {"g_V_hasLabelXnull_personX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel((string) null,"person")}}, + {"g_V_hasLabelXnull_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel(null,null)}}, + {"g_V_hasLabelXnull_personX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel(null,"person")}}, {"g_E_hasLabelXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().HasLabel((string) null)}}, {"g_E_hasXlabel_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Has(T.Label,(object) null)}}, {"g_V_properties_hasLabelXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().HasLabel((string) null)}}, diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/BytecodeGeneration/BytecodeGenerationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/BytecodeGeneration/BytecodeGenerationTests.cs index b8859ec..adac06b 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/BytecodeGeneration/BytecodeGenerationTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Process/Traversal/BytecodeGeneration/BytecodeGenerationTests.cs @@ -21,6 +21,7 @@ #endregion +using System; using Gremlin.Net.Process.Traversal; using Xunit; @@ -95,5 +96,21 @@ namespace Gremlin.Net.IntegrationTest.Process.Traversal.BytecodeGeneration Assert.Empty(bytecode.SourceInstructions); Assert.Empty(bytecode.StepInstructions); } + + [Fact] + public void AnonymousTraversal_VXnullX() + { + var bytecode = __.V(null).Bytecode; + + Assert.Single(bytecode.StepInstructions); + Assert.Single(bytecode.StepInstructions[0].Arguments); + Assert.Null(bytecode.StepInstructions[0].Arguments[0]); + } + + [Fact] + public void AnonymousTraversal_OutXnullX() + { + Assert.Throws<ArgumentNullException>(() => __.Out(null)); + } } } \ No newline at end of file
