Hi everyone,

sorry for writing such a long email, but this design
decision is very important for the completion of the
Reflection component.

Sebastian Bergmann wrote:
> Stefan Marr schrieb:
>> And there has been a discussion to include another Interface definition in
>> between the reflection classes and the underlying infrastructure, to be able
>> to use a parser and handle Reflection without loading the classes. Butdon't
>> know how that much about this idea. Falko?
> 
>  Yes, Static Reflection (ie. being able to use the Reflection API without
>  the class being loaded) is something I would really like to see in the
>  component.

Recently I studied several approaches for the integration of
the Static Reflection concept we developed at the FrOSCon.

The idea we discussed at the conference was not to include
the parser for static analysis directly in the ezcReflection
component (at least for the first release).
Instead we wanted to introduce a layer of interface which
should then be implemented by ezcReflection and Static
Reflection classes. This would allow for tools like
ezcCodeAnalyzer, ezcWsdl or PHPCallGraph to leverage both
reflection implementations.

Jakob and me developed some tools to generate PHP code out
of reflection objects. You may have a look at them in our
Subversion repositories at:
svn://svn.pureenergy.cc/staticReflection
https://instantsvc.svn.sourceforge.net/svnroot/instantsvc/branches/reflection2php

Interestingly we discovered that this kind of code
generation can be leveraged for refactoring and quality
assurance. On the one hand the tools enable the generation
of interfaces out of classes or class skeletons out of
interfaces. On the other hand it allows for comparing
properties and method signatures among various classes,
e.g. between ezcReflection classes and the PHP Reflection
API. (Try a Diff-Viewer on the output in the svn.)

However the design with interfaces does not seem
to be very elegant because it would require a
complete reimplementation of nearly all features
of the ezcReflection component in the Static
Reflection classes. Thus I propose a dependency injection
approach:
We could allow the injection of instances of external
Reflection implementations through the constructors of the
ezcReflection classes. Such an external Reflection
implementation would have to extend the PHP reflection
classes as well as the ezcReflection does. If such an
instance is given the ezcReflection would leverage it as its
data source. Otherwise PHP Reflection would be utilized as
usual. Additional features of the external instance could
also be leveraged by forwarding calls via overloading.

class ezcReflectionClass extends ReflectionClass
{
     protected $class;

     /**
      * @param string|object|ReflectionClass $argument
      *        name, instance or ReflectionClass object of
      *        the class to be reflected
      */
     public function __construct( $argument )
     {
         if ( !$argument instanceof ReflectionClass )
         {
             parent::__construct($argument);
         }
        $this->class = $argument;
        ...
     }

     public function getName() {
         if ( $this->class instanceof ReflectionClass )
         {
             // query external reflection object
             $name = $this->class->getName();
         } else {
             $name = parent::getName();
         }
         return $name;
     }

     public function __call( $method, $arguments )
     {
         if ( !$this->class instanceof ReflectionClass )
         {
             return call_user_method(
                 $this->class,
                 $method, $arguments
             );
         } else {
             throw new Exception(
                 'Call to undefined method '
                 . __CLASS__ . '::' . $method
             );
         }
     }

     ...
}

This aproach would enable users of the ezcReflection to
leverage various reflection extensions (e.g.
StaticReflection or a version extended with intercession
features of Runkit as Stefan proposed it) together with the
annotation mechanism and the type system.
Furthermore the reimplementation of all methods would allow
us to provide a complete documentation since the section of
the PHP manual is more or less incomplete.

Do you have any other ideas on how to solve this integration
problem or improve the proposed design?

Kind regards,
Falko


-- 
Components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/components

Reply via email to