protected final function buildFunction(IFunction $function, callable $factory)
{
if ($function instanceof CallableFunction) {
$reflection = $this->functionInterpreter->getReflection($function->getCallable());
$scopeType = $reflection->getScope()->getScopeType();
$namespace = $reflection->getInnerReflection()->getNamespaceName() ?: null;
$parameterExpressions = $reflection->getSignature()->getParameterExpressions();
$scopedVariableNames = $reflection->getSignature()->isStatic() ? [] : ['this'];
$scopedVariableNames = array_merge($scopedVariableNames, $reflection->getSignature()->getScopedVariableNames() ?: []);
$bodyExpressions = $reflection->getInnerReflection()->isUserDefined() ? $this->functionInterpreter->getStructure($reflection)->getBodyExpressions() : null;
} elseif ($function instanceof ClosureExpressionFunction) {
if ($function->hasEvaluationContext()) {
$scopeType = $function->getEvaluationContext()->getScopeType();
$namespace = $function->getEvaluationContext()->getNamespace();
} else {
$scopeType = null;
$namespace = null;
}
$expression = $function->getExpression();
$parameterExpressions = $expression->getParameters();
$bodyExpressions = $expression->getBodyExpressions();
$scopedVariableNames = array_merge(['this'], $expression->getUsedVariableNames());
} else {
throw new PinqException('Cannot build function: unsupported function type, %s', get_class($function));
}
return $factory($this->getFunctionCallableParameter($function), $scopeType, $namespace, $this->getFunctionScopeParameterMap($function, $scopedVariableNames), $parameterExpressions, $bodyExpressions);
}