-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Prevent calling twig_get_attribute by generating the guessed PHP code instead #3928
base: 3.x
Are you sure you want to change the base?
Prevent calling twig_get_attribute by generating the guessed PHP code instead #3928
Conversation
I would say that level 2+ should not exist as they break templates (and falling back to And the big question is whether level 1 can be implemented without any behavior changes for template authors:
|
@stof thank you for your quick reaction to this ❤️ I am not yet aware of all your features you have as I am a Twig user, that is "quite far away" of using it directly. I just place Twig files in a folder and the rest happens. Is there more documentation regarding sandboxing than in the docs folder to read upon? And how do I get nice error messages? I might be spoiled by Symfony Twig Bundle features, that I likely cannot distinguish from Twig alone. I must admit, that I am looking forward to be able to reach level 2 to have a smaller compiled Twig cache and level 3 to not break silently. From my point of view I use Twig because of the inheritance, overrides features and auto escaping. Otherwise I would use PHP instead as it is inherently a good templating engine. If I can get rid of the Don't get me wrong: Twig is not that slow. It just happened, that I was able to make it slow likely with lots of files, blocks, nested objects and sets. |
…rpreted before body so type hints can be referenced correctly
6fa36e8
to
bbb2b43
Compare
bbb2b43
to
c6c29b5
Compare
Interesting! I've actually asked the maintainer of the Symfony Support plugin for PhpStorm to change the auto-complete to default to long form. My reason was to make it easier to find and refactor callers of class methods/properties. But I see that performance could also be improved if the Twig compiler bypassed I'm planning for TwigStan (static code analysis for Twig templates) to warn about invalid code, but maybe it would be worth it to add a notice when code uses a short-hand. |
Hi @drjayvee thank you for reaching out. I see TwigStan to be a good place for it because I do not want to pull in phpstan capabilities into Twig core. But having it would make the code more performant. Having the exact notation for array and method call improves but is difficult to handle for third party templates therefore I try to improve the core instead of everybody else. Fun thing I recently discussed with @keulinho and we were both confused why Haehnchen/idea-php-symfony2-plugin#2024 (comment) already worked although we were pretty sure it did not :D |
Actually, it turns out I was wrong! All the more reason for TwigStan to check whether properties/methods actually exist. Unfortunately, it's not looking too good for PR 4009. :/ |
Due to the CST vs AST discussion? |
Exactly.
|
Now that we have #4165 merged, maybe the work here could be resumed. I'm not convinced that we will be able to do much, but still an interesting topic to explore. |
I can only see this working when
My WIP project TwigQI intends to ensure that first part. I'd be super happy if Twig core does that, probably depending on configuration (e.g. Alternatively, without the guaranteed type, the compiler could go ahead and use the actual method call and then fail (pretty hard) at runtime. |
Once upon a time I had to find out why a twig template is slow (350ms). In my SPX icicle graph I saw
twig_get_attribute
being used quite often and is taking some time:At this time I started to dig into what this method does. If I get it right it guesses whatever how to get to the next value by a given attribute as it tries to get one step deeper from the dot-path notation we use everywhere. I see that this is needed for such a dynamically typed language that is the base for this.
A template like this
{{ foo.bar }}
could mean:$foo->bar
$foo->bar()
$foo->getBar()
$foo->isBar()
$foo['bar']
I thought it could be at least cached so the choice does not need to be calculated twice but this is only valid if you have the values to render the template. So I have to use something else to improve the performance. Now imagine all the paths one could take for
{{ foo.bar.thing }}
. This can be a lot but if predict the path to be$foo->getBar()->getThing()
because you just pass in your structs with getters and you can know it ahead.For my IDE to support me in programming I use Twig comments with PHP type hints. I thought if this helps me to predict what methods I can call, Twig could use this info as well. PHPStan and Psalm also help me in my daily work as well so maybe we can add some sort of compiler optimizations like we know from C/++:
What I implemented in this pull request is a proof of concept with basic variable type cache for different scopes. These scopes can be influenced by code comments
{# @var type \DateTimeInterface #}
, that you already do, and with a specific block{% type "DateTimeInterface" %}
to be more specificly integrated into the language so one could differ between IDE hints and language specific hints. I already have scopes by BodyNode and WithNode. Types that can be extracted from simple expressions are understood without type hints (e.g. array expressions). I prepared code, that wants to behave like level 2 optimization but level 1 could be done, when changingsrc/Node/Expression/GetAttrExpression.php:51
by removing thetrue ||
and using acreateAutoInlineSourceCompiler
instead.Open todo / questions:
match
expression to ensure I have macro and other variables at hand without having touse
them in closures, that would be better for lower PHP versions. Can we just use it and expect PHP 8 or do we have to use closures and keep track which vars to use?ClassA|ClassA
generates duplicate codeloop
have type infoThank you for @jkrzefski brainstorming the optimization levels
Thank you for reading and looking into this.