On 1/19/11 10:09 AM, Adam Richardson wrote:
On Wed, Jan 19, 2011 at 8:21 AM, Richard Quadling<rquadling@xxxxxxxxx>wrote:
On 19 January 2011 07:46, Adam Richardson<simpleshot@xxxxxxxxx> wrote:
On Wed, Jan 19, 2011 at 2:07 AM, Larry Garfield<larry@xxxxxxxxxxxxxxxx
wrote:
3) Static analysis. Instead of reflection, either tokenize or string
parse
all files to determine what classes implement what interfaces and then
cache
that information. We are actually using this method now to locate
classes,
and it works surprisingly well. Because we never parse code into memory
it
does not ever spike the memory usage. However, it is impossible to
determine
if a class implements a given interface by static analysis unless it
declare
so itself with the implements keyword. If it does so indirectly via
inheritance, either via the class or via the interface, it would not
find
it.
That necessitates that any "detectable" classes must explicitly
themselves
declare their interfaces, even if it is redundant to do so. I don't
like
that
approach, but it's the first one that strikes me as even viable.
4) Explicit declaration. In this approach we detect nothing and rely on
the
plugin developer to do everything. That is, they must provide somewhere
(either in code or a configuration file) an index of all classes they
offer,
the interfaces they implement, and the file in which they live. While
this
makes the implementation easy, it is a huge burden on the plugin
developer
and
I'm quite sure they'll forget to do so or get it wrong on a regular
basis.
I'd suggest combining 3 and 4. Build a tool that performs a static
analysis
of a group of files and make it easy for developers to use. This tool
would
generate the explicit declarations your codebase would utilize when
answering such questions as "which classes implement interface foo". The
file the static analysis tool generates could be easily hand editable, so
developers could tweak it if they see issues (just in case the static
analysis tool has bugs early on), or for small plugins, just quick crank
out
a couple lines by hand.
As long as the static analysis tool builds a composite of class hierarchy
established in all the files (project wide, at least in terms of the
plugin), you wouldn't have to double declare interfaces so they could be
detected.
Adam
That is essentially #3. The static analysis results could easily be
cached in a human-editable form, but in practice I don't think that will
be viable. The humans who will be running this system will largely be
non-PHP-gurus so asking them to validate the accuracy of a giant PHP
array dumped to a file is going to be a losing battle. If we're
actually building a full graph to determine indirect implementation that
would then preclude pre-deriving information per-plugin and just
shipping a manifest file with each plugin. (I could be convinced of
that as an approach, but that still doesn't solve the indirect
implementation problem.)
There is a pecl extension called inclued [1]& [2] which could be used I
think.
It can be used to produce a list of all the relationships between
included files, so a one off pass of all the class files (simply
include them) and then retrieve the analysis from inclued.
You can now build a class dependency tree from that data and cache it.
Pretty much exactly what you need.
Richard,
While inclued performs a nice analysis of the files included at a given
stage of a script, I don't see that it performs a static analysis of the PHP
contained within the files so Larry could use it to detect the interfaces
implemented in a given set of PHP files.
I looked at the pages:
http://docs.php.net/manual/en/inclued.examples-implementation.php
http://docs.php.net/manual/en/function.inclued-get-data.php
I'm curious about this feature myself, so if I missed something, please let
me know.
Thanks,
Adam
Yeah, inclued looks cool but it looks like a runtime analysis tool, not
a static analysis tool. That runs into the same problem as reflection
where I'd have to include the whole code base in order to build up the
indexes I need.
--Larry Garfield
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php