Problem/Motivation
The original reason for the issue (see below) was fixed in #2631202: Doctrine no longer supports SimpleAnnotationReader, incorporate a solution into core. However, Chi pointed out in #46 that two annotations, internal and property, are still discovered. Those need to be fixed.
--- original problem/motivation ---
Add a class loader like this:
spl_autoload_register( function ($class_name) {
file_put_contents(__DIR__ . '/classes.txt', $class_name . "\n", FILE_APPEND);
},
FALSE, TRUE);
It generates a classes.txt file.
Look at that file like this:
sort classes.txt | uniq -c
You'll see stuff like this:
2 Drupal\Core\Annotation\PluginID
3 Drupal\Core\Annotation\Translation
5 Drupal\Core\Annotation\code
3 Drupal\Core\Annotation\end
3 Drupal\Core\Annotation\end_code
5 Drupal\Core\Annotation\endcode
25 Drupal\Core\Annotation\ingroup
1 Drupal\Core\Annotation\property
11 Drupal\Core\Annotation\see
2 Drupal\Core\Annotation\todo
This means that the classloader is being asked to autoload, for instance, Drupal\Core\Annotation\ingroup 25 times in a front page load.
That's because the annotation system isn't filtering out known-bad annotations.
At absolute best this means that the autoloader has to waste time dealing with this stuff, and at worst has to do a file_exists() for each of these requests.
Proposed resolution
Add internal, property and event to the list of ignored annotations.
Remaining tasks
Review
Commit
User interface changes
N/A
API changes
N/A
Data model changes
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #56 | 2557433-56-fail.patch | 746 bytes | quietone |
| #56 | 2557433-56.patch | 1.52 KB | quietone |
| #56 | 2557433-56-fail.patch | 746 bytes | quietone |
| #53 | 2557433-53.patch | 1.36 KB | quietone |
| #53 | 2557433-53-fail.patch | 664 bytes | quietone |
Comments
Comment #2
mile23This patch illustrates a proof-of-concept solution.
Obviously we don't want to use reflection when we have a good solution in
Doctrine\Common\Annotations\AnnotationReaderalready, which has an API for ignoring some annotations.Add the autoloader to
index.php, as in the original issue, and then observe theclasses.txtfile to see that these annotation-based classes are no longer being requested.Comment #3
neclimdulYuck, I wonder when this happened.
It might be a lot of work but it seems like we might want to try and just grab as many of the PSR-5 annotations as possible just to protect this in the future.
Comment #4
tim.plunkettI'd bet money it was #2090353: Don't require to put the use statement into plugin classes.
Previously we'd use \Doctrine\Common\Annotations\AnnotationReader::addGlobalIgnoredName() like
$reader->addGlobalIgnoredName('file');to filter out @file, but when we switched to SimpleAnnotationReader, we lost that ability.Comment #5
tim.plunkettIf only Doctrine had used more traits, or less
private, this would be a lot less easy.Is this worth an upstream patch?
Comment #6
tim.plunkettNot sure if we have to do this in each method each time (like the upstream AnnotationReader), or if one call here is fine.
We still need addGlobalIgnoredName calls for endlink and file, like before.
Comment #7
mile23OK, so maybe reflection isn't such a bad idea. :-)
The only upstream change needed is that $parser be protected instead of private. We can subclass to our needs after that.
Comment #8
tim.plunkettYes, though it would be nice to have that upstream list of names to ignore.
Comment #9
xanoTo get the list without having to hardcode it elsewhere? That would have the advantage of not having to look after it.
I had to look it up, but the reason we switched to
SimpleAnnotationReaderis stated in #2090353-2: Don't require to put the use statement into plugin classes.Comment #10
dawehnerSo yeah, SimpleAnnotationReader seemed to be the only way to be able to skip the use statements ... which is IMHO worth to do.
Did we considered to just do the following?
Comment #13
mile23The namespace addition lives on
DocParser, andSimpleAnnotationReaderjust sets it. And of courseAnnotationReaderdoesn't give us an accessor for this.If
$parserwere protected (in eitherSimpleAnnotationReaderorAnnotationReader, or both) we could just subclass and change it, while also getting the benefits of the superclass.I'm pretty sure
SimpleAnnotationReadertellsDocParser*not* to use those globally ignored names. Also, the global ignored names array already contains all our tags so we don't have to set them.So basically it's either an upstream fix or we write our own version of
AnnotationReader.The upstream fix is one of two things: Give
AnnotationReadera way to set the namespace, or make$parserprotected so we can subclass to our own needs.However, if you can apply the patch in #10 and then try to repro with the autoloader in the issue summary and get no requests for
\Drupal\whatever\seethen yay.Comment #14
mile23Here's a test. It will fail. :-)
Add more unsupported annotations as needed.
Comment #16
mile23@alexpott's PR for Doctrine: https://github.com/doctrine/annotations/pull/56
Comment #17
mile23This patch creates a new class called
DrupalAnnotationReader. It's mostly a copy-paste of Doctrine'sSimpleAnnotationReader, with all the extra stuff we want.It includes the test from #14, the ignore list from
AnnotationReader, and some of @alexpott's modifications from https://github.com/doctrine/annotations/pull/56That PR for Doctrine has been around since late April, so it doesn't look like they're moving very quickly.
Will do coding standards stuff if this comes back green and there's some consensus.
Comment #20
Ocramius commentedSigh, I really don't understand how this drupal tracker works. Trying again:
- I just rejected https://github.com/doctrine/annotations/pull/56
- see http://www.doctrine-project.org/jira/browse/DCOM-295
Comment #21
mile23Here's the test in #14 combined with the solution in #10, which fails.
Comment #23
dawehnerWell, the alternative is that Drupal just implements our own Annotation Reader
Comment #24
mile23That's #17. :-)
Comment #25
tim.plunkettSo let's get that green.
Comment #26
mile23I thought I might try to tract the intractable again.
There are still a few fails. The most interesting one is
Drupal\system\Tests\Plugin\Discovery\AnnotatedClassDiscoveryTestwhich finds the@fileannotation and thinks it's a plugin annotation.Comment #27
mile23Comment #29
mile23Hi, I'm Mr. Testing. But I neglected to just run the test, which passes. :-)
Re-running the experiment in the issue summary I see no non-plugin annotations slipping in to the autoload, so I think this issue is done. But if anyone wants the test, here it is.
Comment #30
mile23Comment #32
mile23Valid for 8.2.x beta because it's a test improvement.
Removed @file docblock.
Test still passes.
Comment #36
borisson_Removing the needs tests tag, this is just a test and it still makes sense to add this. Moving this issue to RTBC.
Comment #37
alexpottPatch in #32 is not testing anything. The VFS setup doesn't result in any plugins actually being scanned. Here's a test that proves we still have a problem.
Comment #39
mile23Good catch.
So it looks like we do try to autoload all annotation.
Do we want to go back to the earlier attempts at rolling our own reader?
Comment #40
mile23Converted to a dataprovider so we can test all the testcases.
They all still fail except for { and }.
Comment #41
mile23Forgot the interdiff.
Comment #43
mile23I just opened this PR: https://github.com/doctrine/annotations/pull/211
I opened it because DocParser *never* ignores annotations when you also have namespaces, so therefore we can't even roll our own annotation reader.
Comment #45
bradjones1Comment #46
chi commentedprovideBadAnnotationsneeds@internaland@propertytags as they also trigger autoloader. Though they probably need to be included toSimpleAnnotationReader::$ignoredAnnotationsfirst.Comment #49
quietone commentedThis has been fixed, it was done in #2631202: Doctrine no longer supports SimpleAnnotationReader, incorporate a solution into core. The patch here contains one test file and that was added in the other issue.
Closing as a duplicate.
Comment #50
chi commented@quietone I was checking this after #2631202: Doctrine no longer supports SimpleAnnotationReader, incorporate a solution into core has been resolved. See note #46.
Comment #51
andypost@Chi do you mean that issue needs re-title and update summary instead of closing?
Comment #52
chi commentedI would like someone else confirmed #46 first.
Comment #53
quietone commented@Chi, thanks for pointing out my error.
I have updated the IS and provided a fail and success patch.
Comment #54
quietone commentedI forgot to make a more accurate title.
Comment #56
quietone commentedI looked at the list of API documentation and comment standards tag references and I think @event needs to be added to this list. Are there any others?
Comment #58
chi commentedHaving
@eventlisted there makes sense to me. Technically, any other tag can trigger the autoloader. There is little we can do about this. The way Doctrine parses annotations is really odd.Comment #59
quietone commentedOK. Updating title
Comment #63
smustgrave commentedTriggering for 10.1
Comment #64
smustgrave commented10.1 failure in #56 seems to be random ckeditor5
Comment #65
alexpottI think we need to be careful here - I think we'll break this contrib module https://git.drupalcode.org/project/bcubed/-/blob/8.x-1.x/src/Annotation/...
Maybe the right thing here is to just wait for annotations to pass into history?
Comment #66
smustgrave commentedIs there a ticket we can postpone this on then?
Comment #67
chi commented#3252386: Use PHP attributes instead of doctrine annotations ?
Comment #68
smustgrave commentedGood find!
Of course if anyone thinks this shouldn't be postponed please move back to review
Comment #69
berdirPostponed isn't really the right status I'd say. Once that issue and all the follow-ups to convert all annotation based plugins to attributes, this is simply a won't fix this.
I'd be fine to just close it as won't fix/outdated now, the chances that we'll remember to get back to this and do that then seems quite slim.
Doing that, if someone disagrees they can reopen.