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); }
protected final function resolveFunction(IFunction $function) { $callable = $function->getCallable(); $this->resolveParameter($this->getFunctionCallableParameter($function), $function->getCallable()); if ($function instanceof CallableFunction) { $reflection = $this->functionInterpreter->getReflection($callable); $this->resolveFunctionScope($function, $reflection); } elseif ($function instanceof ClosureExpressionFunction) { $expression = $function->getExpression(); $this->hash .= $expression->hash(); if ($function->hasEvaluationContext()) { $evaluationContext = $function->getEvaluationContext(); $this->resolveParameter($this->getFunctionScopedVariableParameter($function, 'this'), $evaluationContext->getThis()); foreach (array_intersect_key($evaluationContext->getVariableTable(), array_flip($expression->getUsedVariableNames())) as $variableName => $value) { $this->resolveParameter($this->getFunctionScopedVariableParameter($function, $variableName), $value); } } } else { throw new PinqException('Cannot resolve function: unsupported function type %s', get_class($function)); } }