Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PSR-0 annotation reader, try #2 #154

Merged
merged 32 commits into from
Jun 30, 2012
Merged

Conversation

chx
Copy link
Contributor

@chx chx commented Jun 18, 2012

This is a radically different approach to the same goal: use less memory. See #152 for some discussion but most of it is irrelevant to this code that's why I opened a new pull request.

Note how most files are new and only Psr0Parser needed to change and even that only in very small ways.

Usage:

$parser = new Psr0Parser('path/to/your/lib', 'Drupal\\block\\Plugins\\owner\\type\\test');
$reader = new AnnotationReader();
var_dump($reader->getPropertyAnnotations($parser->getPropertyReflection('foo')));

If we decide that this is an approach worth pursuing, adding tests will be very easy because Doctrine is PSR-0 itself.

public function getUseStatements() {
return $this->psr0Parser->getUseStatements();
}
static function export($argument, $return = FALSE) { throw new ReflectionException('Method not implemented'); }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is ugly but otherwise PHP fatals. And, some of these could actually be implemented if we wanted to. I didn't :) How much we want this to be generally useable? I voted on the minimal viable approach even if the implementation would be an empty function body like for getExtension.

@stof
Copy link
Member

stof commented Jun 18, 2012

Please follow the Doctrine coding standards (which are more or less PSR-2) for the code you contribute

@chx
Copy link
Contributor Author

chx commented Jun 18, 2012

Sorry. I am old fashioned and still use two spaces. (I wonder however how we managed to end up with four when it's completely unreadable. Oh well.)

The bigger question is, are we happy with this direction? I will add tests, fix coding style, whatnot if we are. I already abandoned one branch so no point in wasting time with that if this won't be merged.

$token = $this->next();
$this->parentClassName = $token[1];
if ($this->parentClassName[0] !== '\\') {
$this->parentClassName = $this->ns . '\\' . $this->parentClass;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work. You can also write:

<?php

namespace Doctrine\Common\Annotations;

use Doctrine\Common as CommonNS;

class Parser extends CommonNS\ParentClass {}

To resolve class names you need all use statements first and then you must resolve the FQN with the help of PHPs name resolution rules.
http://de.php.net/manual/en/language.namespaces.rules.php

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's very useful! Good that we have the use statements parsed already.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it is still not fixed

public function __construct($includePath, $className, $classAnnotationOptimize = FALSE)
{
$this->className = ltrim($className, '\\');
$this->fileName = $includePath . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would mean that all your libraries have to live in the same folder, which is absolutely not a requirement in PSR-0, and will be wrong as soon as you use some vendor libraries in your code (as you will not mix the repositories together)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not get this. You can pass 'vendor/Symfony' or 'vendor/Doctrine' or whatever else. That's why $includePath is an argument.

@stof
Copy link
Member

stof commented Jun 18, 2012

I see an issue: the original PhpParser is a service object: you create one instance and you use it everywhere you need it. And for instance, the AnnotationReader create one PhpParser and uses it for all classes. Your Psr0Parser on the other hand is not such a service object: you can use it only once and have to create a new one for each class.

@stof
Copy link
Member

stof commented Jun 18, 2012

and btw, it will not be usable as a drop-in replacement of the PhpParser: if you inject create a Psr0Parser, the code using the parser would still call the logic of the parent parser.
So your Psr0Parser cannot be used to read the annotations with the Doctrine annotation reader

@chx
Copy link
Contributor Author

chx commented Jun 18, 2012

Sorry I do not understand why this can not be used with the Doctrine annotation reader. Please see the original post on a usage example -- it's working already or at least it seemed to me.

@stof
Copy link
Member

stof commented Jun 18, 2012

Well, you use your parser as a service responsible to instantiate the reflection, not as a parser in the reader. So it is really weird to extend from the parser.

@chx
Copy link
Contributor Author

chx commented Jun 18, 2012

Also, all the Psr0Parser has to do with PhpParser is code reuse , nothing else. It's not a drop-in replacement or anything like that. I just found that PhpParser already has next() and parseUseStatement() so I reused that.

@chx
Copy link
Contributor Author

chx commented Jun 18, 2012

OK, I have moved the common code into a base class to extend from.

@chx
Copy link
Contributor Author

chx commented Jun 18, 2012

Oh and if you don't like that both extend from TokenParser I can just store a TokenParser object in both.

@stof
Copy link
Member

stof commented Jun 18, 2012

Btw, for the Cs issue, PHP-CS-Fixer should be able to fix most of them if you run it on these files

@chx
Copy link
Contributor Author

chx commented Jun 19, 2012

I will write the parent class name resolver next. With the current code I can do $parser = new Psr0Parser(drupal_classloader()->getNameSpaces(), 'Drupal\\block\\Plugins\\owner\\type\\test'); where drupal_classloader returns Symfony\Component\ClassLoader\UniversalClassLoader and in fact the file finder code itself is a straight copy out of UniversalClassLoader.

{
public function __construct($psr0Parser)
{
$this->psr0Parser = $psr0Parser;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should rename the property, and declare it (undeclared properties have a performance impact as PHP 5.4 optimized the property access for known properties)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I know about that in PHP 5.4 and I really tried hard to define all, sorry skipping this one.

@chx
Copy link
Contributor Author

chx commented Jun 28, 2012

So now I have the interface we discussed. Anything else?


namespace Doctrine\Common\Reflection;

interface ReflectionInterface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the curly brace should be on its own line (PHP-CS-Fixer FTW 😄)

}
}

public function findFile()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@beberlei asked you to move this logic to another class implementing an interface and injected inside the parser, so that people can replace it by another implementation if they don't follow PSR-0

* Only retrieve the class docComment. Presumes there is only one
* statement per line.
*/
public function __construct($className, $finder, $classAnnotationOptimize = FALSE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false should be written lowercased (same for true and null but I'm not sure they appear in the PR). The PHP-CS-Fixer does not handle this currently so it has to be fixed by hand

beberlei added a commit that referenced this pull request Jun 30, 2012
PSR-0 annotation reader, try #2
@beberlei beberlei merged commit d2f8a36 into doctrine:master Jun 30, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants