// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
-namespace hoplite\base {
+namespace hoplite\base;
/*!
A WeakInterface is a class that implements some interface and then can bind
*/
class WeakInterface
{
- /*! @var array Map of MethodImps keyed by the method name. */
+ /*! @var array Map of method imps hashes, keyed by the method name. */
private $imps = array();
/*! @var object The object to which this interface is bound. */
$methods = $reflector->GetMethods();
foreach ($methods as $method) {
$name = $method->name;
- $this->imps[$name] = new internal\MethodImp($this, $method);
+ $imp = array(
+ 'method' => $method,
+ 'required' => strpos($method->GetDocComment(), '@required') !== FALSE,
+ );
+ $this->imps[$name] = $imp;
}
}
return;
}
- return $this->imps[$meth]->Invoke($this->object_reflector, $args);
+ try {
+ $imp = $this->object_reflector->GetMethod($meth);
+ } catch (\ReflectionException $e) {
+ if ($this->imps[$meth]['required'])
+ throw $e;
+ return;
+ }
+ return $imp->InvokeArgs($this->object, $args);
}
/*! Ensures that the bound object properly implements the interface. */
}
foreach ($this->imps as $name => $imp) {
- if ($imp->IsRequired() && !isset($by_name[$name]))
+ if ($imp['required'] && !isset($by_name[$name]))
throw new WeakInterfaceException($reflector->name . ' does not implement required interface method ' . $name);
- if (isset($by_name[$name]) && !$imp->Matches($by_name[$name]))
+ if (isset($by_name[$name]) && $imp['method']->GetParameters() != $by_name[$name]->GetParameters())
throw new WeakInterfaceException($reflector->name . '::' . $name . ' does not match interface definition');
}
}
}
class WeakInterfaceException extends \Exception {}
-
-} // namespace hoplite\base
-
-namespace hoplite\base\internal {
-
-/*!
- An encapsulation of a method implementation.
-*/
-class MethodImp
-{
- /*! @var WeakInterface The interface to which this method belongs. */
- private $interface = NULL;
-
- /*! @var ReflectionMethod The method of the actual interface that this is implementing. */
- private $method = NULL;
-
- /*! @var bool Whether or not this is required. */
- private $required = FALSE;
-
- public function __construct(\hoplite\base\WeakInterface $interface,
- \ReflectionMethod $method)
- {
- $this->interface = $interface;
- $this->method = $method;
- $this->required = strpos($this->method->GetDocComment(), '@required') !== FALSE;
- }
-
- /*! Forwards a method call. */
- public function Invoke($reflector, $args)
- {
- try {
- $impl = $reflector->GetMethod($this->method->name);
- } catch (\ReflectionException $e) {
- if ($this->required)
- throw $e;
- return;
- }
- return $impl->InvokeArgs($this->interface->get(), $args);
- }
-
- /*! Performs method signature validation. */
- public function Matches(\ReflectionMethod $method)
- {
- return $method->GetParameters() == $this->method->GetParameters();
- }
-
- /*! Checks if a method is marked as required. */
- public function IsRequired()
- {
- return $this->required;
- }
-}
-
-} // namespace hoplite\base\internal