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/23 08:16:08 UTC
[33/50] tinkerpop git commit: Invoke predicates and enums
Invoke predicates and enums
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/fe6e6131
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/fe6e6131
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/fe6e6131
Branch: refs/heads/TINKERPOP-1827
Commit: fe6e61312d22c6620238ce0ca126816575e48033
Parents: 71c4a8f
Author: Jorge Bay Gondra <jo...@gmail.com>
Authored: Mon Oct 30 15:14:38 2017 +0100
Committer: Jorge Bay Gondra <jo...@gmail.com>
Committed: Thu Nov 23 09:08:06 2017 +0100
----------------------------------------------------------------------
.../StaticTraversalParameter.cs | 15 +--
.../TraversalEnumParameter.cs | 98 ++++++++++++++++++++
.../TraversalEvaluationTests.cs | 16 +++-
.../TraversalEvaluation/TraversalParser.cs | 79 ++++++++++------
.../TraversalPredicateParameter.cs | 26 ++++--
.../TraversalTokenParameter.cs | 71 --------------
6 files changed, 188 insertions(+), 117 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe6e6131/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 8e0fbf9..dca691b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/StaticTraversalParameter.cs
@@ -30,9 +30,11 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
internal class StaticTraversalParameter : ITokenParameter, IEquatable<StaticTraversalParameter>
{
+ private readonly string _traversalText;
+
public bool Equals(StaticTraversalParameter other)
{
- return Parts.SequenceEqual(other.Parts);
+ return Tokens.SequenceEqual(other.Tokens);
}
public override bool Equals(object obj)
@@ -45,12 +47,12 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
public override int GetHashCode()
{
- return Parts != null ? Parts.GetHashCode() : 0;
+ return Tokens != null ? Tokens.GetHashCode() : 0;
}
public object GetValue()
{
- throw new NotImplementedException();
+ return TraversalParser.GetTraversalFromTokens(Tokens, null, _traversalText);
}
public Type GetParameterType()
@@ -58,11 +60,12 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return typeof(ITraversal);
}
- public IList<Token> Parts { get; }
+ public IList<Token> Tokens { get; }
- public StaticTraversalParameter(IList<Token> parts)
+ public StaticTraversalParameter(IList<Token> tokens, string traversalText)
{
- Parts = parts;
+ _traversalText = traversalText;
+ Tokens = tokens;
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe6e6131/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
new file mode 100644
index 0000000..663928a
--- /dev/null
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEnumParameter.cs
@@ -0,0 +1,98 @@
+#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
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Gremlin.Net.Process.Traversal;
+using TEnum = Gremlin.Net.Process.Traversal.T;
+
+namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
+{
+ /// <summary>
+ /// Represents a parameter for a traversal token (ie: T.label)
+ /// </summary>
+ internal class TraversalEnumParameter : ITokenParameter, IEquatable<TraversalEnumParameter>
+ {
+ private readonly string _text;
+
+ private static readonly IDictionary<string, Type> EnumTypesByName = typeof(Scope).GetTypeInfo().Assembly
+ .GetTypes().Where(t => t.GetTypeInfo().IsEnum && t.GetTypeInfo().IsPublic)
+ .ToDictionary(e => e.Name, e => e);
+
+ private readonly object _value;
+ private readonly Type _type;
+
+ public TraversalEnumParameter(string text)
+ {
+ _text = text;
+ var separatorIndex = text.IndexOf('.');
+ var enumTypeName = text.Substring(0, separatorIndex);
+ if (!EnumTypesByName.TryGetValue(enumTypeName, out var type))
+ {
+ throw new KeyNotFoundException($"Enum with name {enumTypeName} not found");
+ }
+ _type = type;
+ var valueName = text.Substring(separatorIndex + 1);
+ _value = Enum.Parse(type, GetCsharpName(valueName));
+ }
+
+ private string GetCsharpName(string valueText)
+ {
+ if (_type == typeof(Direction))
+ {
+ valueText = valueText.ToLower();
+ }
+ return TraversalParser.GetCsharpName(valueText);
+ }
+
+ public bool Equals(TraversalEnumParameter other)
+ {
+ return _text == other._text;
+ }
+
+ 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((TraversalEnumParameter) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return _text.GetHashCode();
+ }
+
+ public object GetValue()
+ {
+ return _value;
+ }
+
+ public Type GetParameterType()
+ {
+ return _type;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe6e6131/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 4e3ec42..9cbceb9 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalEvaluationTests.cs
@@ -54,11 +54,13 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
new[] {new Token("has", new[] {new StringParameter("lang"), new StringParameter("java")})}),
Tuple.Create("g.V().where(__.in(\"knows\"))",
new[] {new Token("where", new[] {new StaticTraversalParameter(
- new[] {new Token("__"), new Token("in", new StringParameter("knows"))})})}),
+ 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[] { new Token("P"), new Token("gt", NumericParameter.Create(27)) }) })})
+ new[] { new Token("P"), new Token("gt", NumericParameter.Create(27)) }) })}),
+ Tuple.Create("g.V().count(Scope.local)",
+ new[] { new Token("count", new TraversalEnumParameter("Scope.local"))})
};
foreach (var item in items)
{
@@ -80,16 +82,20 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
var traversalTexts = new []
{
"g.V().count()",
- "g.V().constant(123)",
+ //"g.V().constant(123L)", Can be parsed using the new type-safe API
"g.V().has(\"no\").count()",
"g.V().values(\"age\")",
"g.V().valueMap(\"name\", \"age\")",
- "g.V().repeat(__.both()).times(5)"
+ "g.V().where(__.in(\"created\").count().is(1)).values(\"name\")",
+ "g.V().count(Scope.local)",
+ "g.V().values(\"age\").is(P.lte(30))"
};
var g = new Graph().Traversal();
foreach (var text in traversalTexts)
{
- Assert.NotNull(TraversalParser.GetTraversal(text, g));
+ var traversal = TraversalParser.GetTraversal(text, g);
+ Assert.NotNull(traversal);
+ Assert.True(traversal.Bytecode.StepInstructions.Count > 0);
}
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe6e6131/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 11283c1..9880a64 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
@@ -42,49 +42,63 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
private static readonly Regex RegexFloat =
new Regex(@"\d+\.\d+f", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex RegexLong = new Regex(@"\d+l", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static readonly Regex RegexEnum = new Regex(@"\w+\.\w+", RegexOptions.Compiled);
internal static ITraversal GetTraversal(string traversalText, GraphTraversalSource g)
{
- Func<GraphTraversalSource, ITraversal> traversalBuilder;
- if (!FixedTranslations.TryGetValue(traversalText, out traversalBuilder))
+ if (!FixedTranslations.TryGetValue(traversalText, out var traversalBuilder))
{
- return BuildFromMethods(traversalText, g);
+ var tokens = ParseTraversal(traversalText);
+ return GetTraversalFromTokens(tokens, g, traversalText);
}
return traversalBuilder(g);
}
- private static ITraversal BuildFromMethods(string traversalText, GraphTraversalSource g)
+ internal static ITraversal GetTraversalFromTokens(IList<Token> tokens, GraphTraversalSource g,
+ string traversalText)
{
- var parts = ParseTraversal(traversalText);
- if (parts[0].Name != "g")
+ ITraversal traversal;
+ Type traversalType;
+ var initialIndex = 2;
+ if (tokens[0].Name == "g")
{
- throw BuildException(traversalText);
+ switch (tokens[1].Name)
+ {
+ case "V":
+ //TODO: support V() parameters
+ traversal = g.V();
+ break;
+ case "E":
+ traversal = g.E();
+ break;
+ default:
+ throw BuildException(traversalText);
+ }
+ traversalType = traversal.GetType();
}
- ITraversal traversal;
- switch (parts[1].Name)
+ else if (tokens[0].Name == "__")
{
- case "V":
- //TODO: support V() parameters
- traversal = g.V();
- break;
- case "E":
- traversal = g.E();
- break;
- default:
- throw BuildException(traversalText);
+ traversal = null;
+ traversalType = typeof(__);
+ initialIndex = 1;
}
- for (var i = 2; i < parts.Count; i++)
+ else
{
- var token = parts[i];
+ throw BuildException(traversalText);
+ }
+ for (var i = initialIndex; i < tokens.Count; i++)
+ {
+ var token = tokens[i];
var name = GetCsharpName(token.Name);
- var method = traversal.GetType().GetMethod(name);
+ var method = traversalType.GetMethod(name);
if (method == null)
{
- throw new InvalidOperationException($"Traversal method '{parts[i]}' not found for testing");
+ throw new InvalidOperationException($"Traversal method '{tokens[i]}' not found for testing");
}
var parameterValues = BuildParameters(method, token, out var genericParameters);
method = BuildGenericMethod(method, genericParameters, parameterValues);
traversal = (ITraversal) method.Invoke(traversal, parameterValues);
+ traversalType = traversal.GetType();
}
return traversal;
}
@@ -155,7 +169,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
}
- private static string GetCsharpName(string part)
+ internal static string GetCsharpName(string part)
{
// Transform to PascalCasing and remove the parenthesis
return char.ToUpper(part[0]) + part.Substring(1);
@@ -268,17 +282,24 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
}
if (text.Substring(i, 3).StartsWith("__."))
{
- return new StaticTraversalParameter(ParseTokens(text, ref i));
- }
- if (text.Substring(i, 2).StartsWith("T."))
- {
- return new TraversalTokenParameter(ParseTokens(text, ref i));
+ var startIndex = i;
+ var tokens = ParseTokens(text, ref i);
+ return new StaticTraversalParameter(tokens, text.Substring(startIndex, i - startIndex));
}
if (text.Substring(i, 2).StartsWith("P."))
{
return new TraversalPredicateParameter(ParseTokens(text, ref i));
}
- return null;
+ var parameterText = text.Substring(i, text.IndexOf(')', i) - i);
+ if (string.IsNullOrWhiteSpace(parameterText))
+ {
+ return null;
+ }
+ if (RegexEnum.IsMatch(parameterText))
+ {
+ return new TraversalEnumParameter(parameterText);
+ }
+ throw new NotSupportedException($"Parameter {parameterText} not supported");
}
private static ITokenParameter ParseNumber(string text, ref int i)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe6e6131/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 8c040b9..0d0dc49 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 System.Reflection;
using Gremlin.Net.Process.Traversal;
namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
@@ -35,7 +36,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
public bool Equals(TraversalPredicateParameter other)
{
- return Parts.SequenceEqual(other.Parts);
+ return Tokens.SequenceEqual(other.Tokens);
}
public override bool Equals(object obj)
@@ -48,12 +49,25 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
public override int GetHashCode()
{
- return Parts != null ? Parts.GetHashCode() : 0;
+ return Tokens != null ? Tokens.GetHashCode() : 0;
}
public object GetValue()
{
- throw new NotImplementedException();
+ var type = typeof(P);
+ object instance = null;
+ for (var i = 1; i < Tokens.Count; i++)
+ {
+ var token = Tokens[i];
+ var method = type.GetMethod(TraversalParser.GetCsharpName(token.Name),
+ BindingFlags.Static | 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()});
+ }
+ return instance;
}
public Type GetParameterType()
@@ -61,11 +75,11 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
return typeof(TraversalPredicate);
}
- public IList<Token> Parts { get; }
+ public IList<Token> Tokens { get; }
- public TraversalPredicateParameter(IList<Token> parts)
+ public TraversalPredicateParameter(IList<Token> tokens)
{
- Parts = parts;
+ Tokens = tokens;
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/fe6e6131/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
deleted file mode 100644
index 9291cd6..0000000
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalTokenParameter.cs
+++ /dev/null
@@ -1,71 +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
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TEnum = Gremlin.Net.Process.Traversal.T;
-
-namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
-{
- /// <summary>
- /// Represents a parameter for a traversal token (ie: T.label)
- /// </summary>
- internal class TraversalTokenParameter : ITokenParameter, IEquatable<TraversalTokenParameter>
- {
- public bool Equals(TraversalTokenParameter other)
- {
- return Parts.SequenceEqual(other.Parts);
- }
-
- 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((TraversalTokenParameter) obj);
- }
-
- public override int GetHashCode()
- {
- 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)
- {
- Parts = parts;
- }
- }
-}
\ No newline at end of file