You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by jo...@apache.org on 2017/11/30 09:19:57 UTC
[13/33] tinkerpop git commit: Invoke traversal methods with generic
parameters
Invoke traversal methods with generic parameters
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/19105a75
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/19105a75
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/19105a75
Branch: refs/heads/TINKERPOP-1827
Commit: 19105a755353959d56359ef09757b52015c893bf
Parents: 6d8ff7d
Author: Jorge Bay Gondra <jo...@gmail.com>
Authored: Fri Oct 27 10:55:20 2017 +0200
Committer: Jorge Bay Gondra <jo...@gmail.com>
Committed: Thu Nov 30 10:00:07 2017 +0100
----------------------------------------------------------------------
.../TraversalEvaluation/ITokenParameter.cs | 13 ++-
.../TraversalEvaluation/NumericParameter.cs | 10 +++
.../StaticTraversalParameter.cs | 11 +++
.../TraversalEvaluation/StringParameter.cs | 10 +++
.../Gherkin/TraversalEvaluation/Token.cs | 15 ++--
.../TraversalEvaluationTests.cs | 23 ++++--
.../TraversalEvaluation/TraversalParser.cs | 86 ++++++++++++++++----
.../TraversalPredicateParameter.cs | 11 +++
.../TraversalTokenParameter.cs | 11 +++
.../Gremlin.Net.IntegrationTest.csproj | 6 +-
10 files changed, 164 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
index 1c940db..5c8197f 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/ITokenParameter.cs
@@ -21,10 +21,21 @@
#endregion
+using System;
+
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
public interface ITokenParameter
{
-
+ /// <summary>
+ /// Gets the value of the parameter
+ /// </summary>
+ object GetValue();
+
+ /// <summary>
+ /// Gets the type of the parameter
+ /// </summary>
+ /// <returns></returns>
+ Type GetParameterType();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
index 9effc17..378680c 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/NumericParameter.cs
@@ -56,6 +56,16 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
return $"NumericParameter<{typeof(T).Name}>({Value})";
}
+
+ public object GetValue()
+ {
+ return Value;
+ }
+
+ public Type GetParameterType()
+ {
+ return typeof(T);
+ }
}
internal static class NumericParameter
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
index b054cbc..8e0fbf9 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
@@ -24,6 +24,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Gremlin.Net.Process.Traversal;
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
@@ -47,6 +48,16 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return Parts != null ? Parts.GetHashCode() : 0;
}
+ public object GetValue()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Type GetParameterType()
+ {
+ return typeof(ITraversal);
+ }
+
public IList<Token> Parts { get; }
public StaticTraversalParameter(IList<Token> parts)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
index ad182b5..82f6cd9 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StringParameter.cs
@@ -65,5 +65,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
return $"{GetType().Name}({Value})";
}
+
+ public object GetValue()
+ {
+ return Value;
+ }
+
+ public Type GetParameterType()
+ {
+ return typeof(string);
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/Token.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/Token.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/Token.cs
index 633e2b5..539be89 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/Token.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/Token.cs
@@ -23,13 +23,15 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
internal class Token : IEquatable<Token>
{
- private static readonly IList<ITokenParameter> EmptyParameters = new ITokenParameter[0];
+ private static readonly IList<ITokenParameter> EmptyParameters =
+ new ReadOnlyCollection<ITokenParameter>(new ITokenParameter[0]);
public bool Equals(Token other)
{
@@ -37,7 +39,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
return false;
}
- return (Parameters ?? EmptyParameters).SequenceEqual(other.Parameters ?? EmptyParameters);
+ return (Parameters).SequenceEqual(other.Parameters);
}
public override bool Equals(object obj)
@@ -59,12 +61,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
public string Name { get; }
- public ICollection<ITokenParameter> Parameters { get; }
+ /// <summary>
+ /// Returns the collection of parameters, can not be null.
+ /// </summary>
+ public IList<ITokenParameter> Parameters { get; }
- public Token(string name, ICollection<ITokenParameter> parameters = null)
+ public Token(string name, IList<ITokenParameter> parameters = null)
{
Name = name;
- Parameters = parameters;
+ Parameters = parameters ?? EmptyParameters;
}
public Token(string name, ITokenParameter parameter)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
----------------------------------------------------------------------
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 ea65cd2..0949ad5 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
@@ -22,12 +22,10 @@
#endregion
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
+using Gremlin.Net.Structure;
using Xunit;
using Xunit.Abstractions;
-using Xunit.Sdk;
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
@@ -41,7 +39,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
}
[Fact]
- public void Traversal_Parser_Should_Parse_Parts()
+ public void Traversal_Parser_Should_Parse_Into_Tokens()
{
var items = new[]
{
@@ -64,7 +62,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
};
foreach (var item in items)
{
- var parts = TraversalParser.ParseParts(item.Item1);
+ var parts = TraversalParser.ParseTraversal(item.Item1);
_output.WriteLine("Parsing " + item.Item1);
if (parts[parts.Count-1].Parameters != null)
{
@@ -75,5 +73,20 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
Assert.Equal(new[] {new Token("g"), new Token("V")}.Concat(item.Item2), parts);
}
}
+
+ [Fact]
+ public void GetTraversal_Should_Invoke_Traversal_Methods()
+ {
+ var traversalTexts = new string[]
+ {
+ "g.V().count()",
+ "g.V().constant(123)"
+ };
+ var g = new Graph().Traversal();
+ foreach (var text in traversalTexts)
+ {
+ TraversalParser.GetTraversal(text, g);
+ }
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
----------------------------------------------------------------------
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 0ac97ff..65ca103 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
@@ -56,49 +56,103 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
private static ITraversal BuildFromMethods(string traversalText, GraphTraversalSource g)
{
- var parts = traversalText.Split('.');
- if (parts[0] != "g")
+ var parts = ParseTraversal(traversalText);
+ if (parts[0].Name != "g")
{
throw BuildException(traversalText);
}
ITraversal traversal;
- switch (parts[1])
+ switch (parts[1].Name)
{
- case "V()":
+ case "V":
+ //TODO: support V() parameters
traversal = g.V();
break;
- case "E()":
+ case "E":
traversal = g.E();
break;
default:
throw BuildException(traversalText);
}
- for (var i = 2; i < parts.Length; i++)
+ for (var i = 2; i < parts.Count; i++)
{
- var name = GetCsharpName(parts[i], traversalText);
+ var token = parts[i];
+ var name = GetCsharpName(token.Name);
var method = traversal.GetType().GetMethod(name);
if (method == null)
{
throw new InvalidOperationException($"Traversal method '{parts[i]}' not found for testing");
}
- if (method.IsGenericMethod)
+ var parameters = BuildParameters(method, token, out var genericParameters);
+ method = BuildGenericMethod(method, genericParameters);
+ traversal = (ITraversal) method.Invoke(traversal, parameters);
+ }
+ return traversal;
+ }
+
+ private static MethodInfo BuildGenericMethod(MethodInfo method, IDictionary<string, Type> genericParameters)
+ {
+ if (!method.IsGenericMethod)
+ {
+ return method;
+ }
+ var genericArgs = method.GetGenericArguments();
+ var types = new Type[genericArgs.Length];
+ for (var i = 0; i < genericArgs.Length; i++)
+ {
+ var name = genericArgs[i].Name;
+ if (genericParameters.TryGetValue(name, out var type))
+ {
+ types[i] = type;
+ }
+ //TODO: Try to infer it from the name based on modern schema
+ else
{
throw new InvalidOperationException(
- $"Can not build traversal to test as '{name}()' method is generic");
+ $"Can not build traversal to test as '{method.Name}()' method is generic and type '{name}'" +
+ $" can not be inferred");
}
- traversal = (ITraversal) method.Invoke(traversal, new object[] { new object[0]});
}
- return traversal;
+ return method.MakeGenericMethod(types);
}
- private static string GetCsharpName(string part, string traversalText)
+ private static object[] BuildParameters(MethodInfo method, Token token,
+ out IDictionary<string, Type> genericParameterTypes)
{
- if (!part.EndsWith("()"))
+ var paramsInfo = method.GetParameters();
+ var parameters = new object[paramsInfo.Length];
+ genericParameterTypes = new Dictionary<string, Type>();
+ for (var i = 0; i < paramsInfo.Length; i++)
{
- throw BuildException(traversalText);
+ var info = paramsInfo[i];
+ object value = null;
+ if (token.Parameters.Count > i)
+ {
+ var tokenParameter = token.Parameters[i];
+ value = tokenParameter.GetValue();
+ if (info.ParameterType.IsGenericParameter)
+ {
+ // We've provided a value for parameter of a generic type, we can infer the
+ // type of the generic argument based on the parameter.
+ // For example, in the case of `Constant<E2>(E2 value)`
+ // if we have the type of value we have the type of E2.
+ genericParameterTypes.Add(info.ParameterType.Name, tokenParameter.GetParameterType());
+ }
+ }
+ parameters[i] = value ?? GetDefault(info.ParameterType);
}
+ return parameters;
+ }
+
+ public static object GetDefault(Type type)
+ {
+ return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
+ }
+
+ private static string GetCsharpName(string part)
+ {
// Transform to PascalCasing and remove the parenthesis
- return char.ToUpper(part[0]) + part.Substring(1, part.Length - 3);
+ return char.ToUpper(part[0]) + part.Substring(1);
}
private static Exception BuildException(string traversalText)
@@ -106,7 +160,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return new InvalidOperationException($"Can not build a traversal to test from '{traversalText}'");
}
- internal static IList<Token> ParseParts(string traversalText)
+ internal static IList<Token> ParseTraversal(string traversalText)
{
var index = 0;
return ParseTokens(traversalText, ref index);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
index d9bf061..8c040b9 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalPredicateParameter.cs
@@ -24,6 +24,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Gremlin.Net.Process.Traversal;
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
@@ -50,6 +51,16 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return Parts != null ? Parts.GetHashCode() : 0;
}
+ public object GetValue()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Type GetParameterType()
+ {
+ return typeof(TraversalPredicate);
+ }
+
public IList<Token> Parts { get; }
public TraversalPredicateParameter(IList<Token> parts)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalTokenParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalTokenParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalTokenParameter.cs
index 5a5e8c1..9291cd6 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalTokenParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalTokenParameter.cs
@@ -24,6 +24,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using TEnum = Gremlin.Net.Process.Traversal.T;
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
@@ -50,6 +51,16 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return Parts != null ? Parts.GetHashCode() : 0;
}
+ public object GetValue()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Type GetParameterType()
+ {
+ return typeof(TEnum);
+ }
+
public IList<Token> Parts { get; }
public TraversalTokenParameter(IList<Token> parts)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/19105a75/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
index 40552ad..c929575 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
@@ -18,6 +18,7 @@
<ProjectReference Include="..\..\src\Gremlin.Net\Gremlin.Net.csproj" />
</ItemGroup>
<ItemGroup>
+ <PackageReference Include="gherkin" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />
@@ -30,9 +31,4 @@
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
- <ItemGroup>
- <Reference Include="Gherkin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
- <HintPath>..\..\..\..\temp\Gherkin.dll</HintPath>
- </Reference>
- </ItemGroup>
</Project>
\ No newline at end of file