use of org.apache.atlas.groovy.ClosureExpression.VariableDeclaration in project incubator-atlas by apache.
the class FunctionGenerator method createFunctionIfNeeded.
/**
* Creates a function whose body goes from the child of parentExpr
* up to (and including) the functionBodyEndExpr.
* @param parentExpr
*/
private void createFunctionIfNeeded(AbstractFunctionExpression parentExpr) {
GroovyExpression potentialFunctionBody = parentExpr.getCaller();
if (creatingFunctionShortensGremlin(potentialFunctionBody)) {
GroovyExpression functionCall = null;
if (nextFunctionBodyStart instanceof AbstractFunctionExpression) {
//The function body start is a a function call. In this
//case, we generate a function that takes one argument, which
//is a graph traversal. We have an expression tree that
//looks kind of like the following:
//
// parentExpr
// /
// / caller
// |/_
// potentialFunctionBody
// /
// / caller
// |/_
// ...
// /
// / caller
// |/_
// nextFunctionBodyStart
// /
// / caller
// |/_
// oldCaller
//
//
// Note that potentialFunctionBody and nextFunctionBodyStart
// could be the same expression. Let's say that the next
// function name is f1
//
// We reshuffle these expressions to the following:
//
// parentExpr
// /
// / caller
// |/_
// f1(oldCaller)
//
//
// potentialFunctionBody <- body of new function "f1(GraphTraversal x)"
// /
// / caller
// |/_
// ...
// /
// / caller
// |/_
// nextFunctionBodyStart
// /
// / caller
// |/_
// x
//
// As an example, suppose parentExpr is g.V().or(x,y).has(a).has(b).has(c)
// where has(a) is nextFunctionBodyStart.
//
// We generate a function f1 = { GraphTraversal x -> x.has(a).has(b) }
// parentExpr would become : f1(g.V().or(x,y)).has(c)
AbstractFunctionExpression nextFunctionBodyStartFunction = (AbstractFunctionExpression) nextFunctionBodyStart;
String variableName = "x";
IdentifierExpression var = new IdentifierExpression(variableName);
GroovyExpression oldCaller = nextFunctionBodyStartFunction.getCaller();
nextFunctionBodyStartFunction.setCaller(var);
currentFunctionName = context.addFunctionDefinition(new VariableDeclaration(factory.getTraversalExpressionClass(), "x"), potentialFunctionBody);
functionCall = new FunctionCallExpression(potentialFunctionBody.getType(), currentFunctionName, oldCaller);
} else {
//The function body start is a not a function call. In this
//case, we generate a function that takes no arguments.
// As an example, suppose parentExpr is g.V().has(a).has(b).has(c)
// where g is nextFunctionBodyStart.
//
// We generate a function f1 = { g.V().has(a).has(b) }
// parentExpr would become : f1().has(c)
currentFunctionName = context.addFunctionDefinition(null, potentialFunctionBody);
functionCall = new FunctionCallExpression(potentialFunctionBody.getType(), currentFunctionName);
}
//functionBodyEnd is now part of a function definition, don't propagate it
nextFunctionBodyStart = null;
parentExpr.setCaller(functionCall);
}
}
use of org.apache.atlas.groovy.ClosureExpression.VariableDeclaration in project incubator-atlas by apache.
the class OptimizationContext method addFunctionDefinition.
public String addFunctionDefinition(VariableDeclaration decl, GroovyExpression body) {
String functionName = getUniqueFunctionName();
List<VariableDeclaration> decls = (decl == null) ? Collections.<VariableDeclaration>emptyList() : Collections.singletonList(decl);
ClosureExpression bodyClosure = new ClosureExpression(body, decls);
VariableAssignmentExpression expr = new VariableAssignmentExpression(functionName, bodyClosure);
initialStatements.add(expr);
functionBodies.put(functionName, bodyClosure);
return functionName;
}
Aggregations